Files
zszq-trs/Framework/YLErp.Core/Configuration/ProjectSettings.cs
T
tengyufan e5a1ca1f68 fix: 收益互换OA移动审批改为内部定时轮询
- 复用 HostedTaskService 定时器轮询待处理的 OA 移动审批状态
- 增加单实例防重入控制,避免同一进程内重复同步
- 新增 Erp.TradeApprovalOaSyncIntervalSeconds 配置,默认 30 秒
- 支持在 Admin 全局配置页修改查询间隔,保存后立即生效,无需重启
- 补充 AppConfig 初始化 SQL,不再依赖 PowerJob 或 XXL-JOB 外部调度
2026-08-21 16:48:37 +08:00

857 lines
29 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Newtonsoft.Json;
using System.Reflection;
using YLErp.Configuration;
using YLErp.Configuration.Enums;
using static YLErp.DBModels.Consts.ConsReport;
namespace YLErp
{
public static class PS
{
static ErpConfig _erpConfig;
public static ProjectConfig Config { get; private set; }
public static void ResetConfig(string jsonConfig)
{
if (string.IsNullOrWhiteSpace(jsonConfig))
{
throw new ArgumentNullException(nameof(jsonConfig));
}
_erpConfig = JsonHelper.Deserialize<ErpConfig>(jsonConfig);
Config = new ProjectConfig(_erpConfig);
}
public static IErpConfig GetErpConfig()
{
return _erpConfig;
}
public static bool SetConfig(string name, string value)
{
if (name is null)
{
throw new ArgumentNullException(nameof(name));
}
var index = name.LastIndexOf('.');
if (index >= 0)
{
name = name.Substring(index + 1);
}
var p = typeof(ErpConfig).GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);
if (p == null)
{
return false;
}
var ptype = p.PropertyType;
object objValue;
if (ptype.IsEnum)
{
objValue = Enum.Parse(ptype, value);
}
else if (ptype == typeof(bool))
{
objValue = value == "true";
}
else if (ptype == typeof(int))
{
objValue = int.TryParse(value, out var n) ? n : default;
}
else if (ptype == typeof(double))
{
objValue = double.TryParse(value, out var n) ? n : default;
}
else if (ptype == typeof(decimal))
{
objValue = decimal.TryParse(value, out var n) ? n : default;
}
else
{
objValue = Convert.ChangeType(value, ptype);
}
p.SetValue(_erpConfig, objValue);
return true;
}
class ErpConfig : IErpConfig
{
/// <summary>
///
/// </summary>
public CompanyEnum Company { get; set; }
/// <summary>
/// 公司名称缩写
/// </summary>
public string CompanyAbbreviation { get; set; } = "Default";
/// <summary>
/// 公司名称
/// </summary>
public string CompanyName { get; set; } = "公司";
/// <summary>
/// 公司英文名称
/// </summary>
public string CompanyEnName { get; set; } = "Company";
/// <summary>
/// 公司简称,如:国泰君安
/// </summary>
public string CompanyShortName { get; set; } = "公司";
/// <summary>
/// 公司全名
/// </summary>
public string CompanyFullName { get; set; } = "公司";
/// <summary>
/// 波动率模式
/// </summary>
public VolModeEnum VolMode { get; set; } = VolModeEnum.TradeVol;
/// <summary>
/// 是否检查密码符合监管要求
/// </summary>
public bool CheckPassword { get; set; }
/// <summary>
/// 是否在风险对冲页面采用自动对冲策略
/// </summary>
[JsonProperty("UseHedgingRule")]
public bool IsUseHedgingRule { get; set; }
/// <summary>
/// 自动生成交易确认书、结算单、提前终止确认书等
/// </summary>
[JsonProperty("AutoGenerateContracts")]
public bool IsAutoGenerateContracts { get; set; }
/// <summary>
/// 是否支持简洁版的出入金导入
/// </summary>
public bool SupportEntryExitSimpleVersion { get; set; } = true;
/// <summary>
/// RealTime相关信息通知的角色
/// </summary>
public string RealTimeServiceNotifyRoles { get; set; } = "";
/// <summary>
/// 是否显示RealTime相关信息通知
/// </summary>
public bool ShowRealTimeServiceNotify { get; set; }
/// <summary>
/// 资金记录页面是否显示和客户的其他资金往来记录
/// </summary>
[JsonProperty("ShowOtherClientCash")]
public bool IsShowOtherClientCash { get; set; } = false;
/// <summary>
/// 部署组件版本
/// </summary>
public ComponentVersion ComponentVersion { get; set; } = ComponentVersion.MarketMaker;
public bool CanSelectCreditVariety { get; set; } = true;
/// <summary>
/// 银行账户只能在下拉中选择
/// </summary>
[JsonProperty("BankOnlyDropDown")]
public bool IsBankOnlyDropDown { get; set; }
/// <summary>
/// 授信控制
/// </summary>
[JsonProperty("IsCreditLimit")]
public bool IsCreditLimit { get; set; }
/// <summary>
///
/// </summary>
[JsonProperty("EodSendMaturityEmail")]
public bool IsEodSendMaturityEmail { get; set; } = true;
/// <summary>
///
/// </summary>
public bool UseOldGenerateBook { get; set; } = true;
/// <summary>
///
/// </summary>
public bool ShowAccruedTotalPnL { get; set; }
/// <summary>
///
/// </summary>
public bool IsExportEntryexit { get; set; }
/// <summary>
///
/// </summary>
public bool UseSingleLogin { get; set; }
public bool UseDisplayNotional { get; set; }
/// <summary>
///
/// </summary>
public bool IsShowCompanyCash { get; set; }
/// <summary>
/// 是否在盯市报告资金状态里面显示总盈亏
/// </summary>
public bool TradeMarketShowTotalNetSettlement { get; set; }
/// <summary>
///
/// </summary>
[JsonProperty("AmendableAfterConfirm")]
public bool IsAmendableAfterConfirm { get; set; }
/// <summary>
/// 是否是在确认书生成后才能执行
/// </summary>
public bool ExecuteAfterGeneratedConfirmDoc { get; set; } = true;
/// <summary>
/// 美式提前行权是否和到期行权用相同的结算单模板),默认值为True
/// </summary>
[JsonProperty("SingleExecutionTemplate")]
public bool IsSingleExecutionTemplate { get; set; } = true;
/// <summary>
/// GenerateAmendDoc如果为true,在保存修改信息时,生成一个交易变更确认书文档并下载
/// </summary>
[JsonProperty("GenerateAmendDoc")]
public bool IsGenerateAmendDoc { get; set; } = true;
/// <summary>
/// 持仓市值是否进行四舍五入处理
/// </summary>
public bool IsPVRounded { get; set; }
/// <summary>
/// 自定义交易收盘时是否跳过验证自定义风险指标
/// </summary>
public bool IsMustRiskManual { get; set; }
/// <summary>
/// 模板或者其他相关文件的路径
/// </summary>
public string DocPath { get; set; }
/// <summary>
/// 追保通知里是否加上额外追保
/// </summary>
public bool NeedAdditionalMargin { get; set; }
/// <summary>
/// 在收盘时使用老的EodPnLExplainer方法
/// </summary>
public bool UseOldEodPnLExplainer { get; set; } = true;
/// <summary>
/// 平值期权报价,当到期日是非交易日时,是否向前移;如果false,则向后移
/// </summary>
public bool AtmQuotePreviousBizDayAdjust { get; set; } = true;
/// <summary>
/// 是否采用SkewMap的方法构造波动率,目前只有光大光子采用此模式
/// </summary>
public bool SkewMapVolConstruction { get; set; } = false;
/// <summary>
/// 在报价中,TTM是否精确到分钟级别
/// </summary>
public bool PrecisionOfMinuteInQuote { get; set; } = false;
/// <summary>
/// 波动率曲面上的日期节点的shift规则
/// </summary>
public VolSurfaceKeyDateShiftEnum VolSurfaceKeyDateShift { get; set; } = VolSurfaceKeyDateShiftEnum.None;
/// <summary>
/// 波动率曲面的期限,是否不包含截止日期
/// 例如,估值日为2019-04-091M期限:
/// 当VolSurfaceTermExcludeEndDate为true,则到期日为2019-05-08
/// 当VolSurfaceTermExcludeEndDate为false,则到期日为2019-05-09
/// </summary>
public bool VolSurfaceTermExcludeEndDate { get; set; } = false;
/// <summary>
/// 双向预付金
/// </summary>
public bool TwoSideMargin { get; set; } = false;
/// <summary>
/// 是否展示计算维持预付金的Spv
/// </summary>
public bool NeedShowSpv { get; set; } = false;
/// <summary>
/// 是否是权益类预付金算法
/// </summary>
public bool IsStockMargin { get; set; } = false;
/// <summary>
/// 结算报告是否显示持仓预付金
/// </summary>
public bool PositionDetialShowMargin { get; set; } = false;
/// <summary>
/// TapConsoleWebServer
/// </summary>
public string TapConsoleWebServer { get; set; }
/// <summary>
/// Web Base Url
/// </summary>
public string YLErpWebUrl { get; set; }
/// <summary>
/// 是否使用更加精确的波动率
/// </summary>
public bool VolMoreAccurate { get; set; } = false;
/// <summary>
/// 是否包含客户端
/// </summary>
public bool HasClientSide { get; set; } = false;
/// <summary>
/// 客户端是否可以注册
/// </summary>
public bool HasClientSign { get; set; } = false;
/// <summary>
/// 公司ID(由镒链分配)
/// </summary>
public string CompanyID { get; set; }
/// <summary>
/// 客户上传文件审核是否启用
/// </summary>
public bool ClientFileAudit { get; set; } = false;
/// <summary>
/// 客户上传文件审核记录
/// </summary>
public string ClientFileAuditItems { get; set; }
/// <summary>
/// Qdp计算的并行度,小于等于1时代表不并行;该数字不要超过机器的CPU核数
/// </summary>
public int QdpParallelDegree { get; set; } = 4;
/// <summary>
/// 外部定价引擎服务的Url地址
/// </summary>
public string ExternalPricingServiceUrl { get; set; }
/// <summary>
/// 确认书用印记录
/// </summary>
public bool ConfirmBookStampStatus { get; set; } = false;
/// <summary>
/// 板块性质别名配置
/// </summary>
public string UnderlyingBlockConfig { get; set; }
/// <summary>
/// 交易编号必须大写
/// </summary>
public bool UpperTradeNumber { get; set; }
/// <summary>
/// 交易编号是否允许修改
/// </summary>
public bool CanEditTradeNumber { get; set; }
/// <summary>
/// 能否设置和导出成交溢价和了结溢价
/// </summary>
public bool CanSetTradePremium { get; set; }
/// <summary>
/// 场内期权是否使用行情价收盘
/// </summary>
public bool ExchangeOptionSettleByPrice { get; set; }
/// <summary>
/// 是否在实时风险中计算凤凰和雪球的所有greeks
/// </summary>
public bool CalcAutocallGreeksInRisk { get; set; }
/// <summary>
/// 多标的组合交易时使用单标的最大名义本金
/// </summary>
public bool UseStockEqvNotionalMax { get; set; }
/// <summary>
/// 券商环境
/// </summary>
public bool SecuritiesEnvironment { get; set; }
/// <summary>
/// 证券业报送定期报告最大可报告月
/// </summary>
public int ReportMaxMonth { get; set; }
/// <summary>
/// 只是用结算确认书页面
/// </summary>
public bool SettlementPageV2 { get; set; }
/// <summary>
/// FTP连接方式是否为被动模式
/// </summary>
public bool SAC_FtpUsePassive { get; set; }
/// <summary>
/// 远程地址
/// </summary>
public string SAC_RemotePath { get; set; }
private string _sac_RemotePath_Outbox;
/// <summary>
/// 发件箱远程地址
/// </summary>
public string SAC_RemotePath_Outbox
{
get
{
if (string.IsNullOrWhiteSpace(_sac_RemotePath_Outbox))
{
return SAC_RemotePath;
}
return _sac_RemotePath_Outbox;
}
set
{
_sac_RemotePath_Outbox = value;
}
}
/// <summary>
/// FTP是否启用SSL
/// </summary>
public bool SAC_EnableSsl { get; set; }
/// <summary>
/// 登录远程地址的用户名
/// </summary>
public string SAC_RemoteUser { get; set; }
/// <summary>
/// 登录远程地址的密码
/// </summary>
public string SAC_RemotePassword { get; set; }
/// <summary>
/// 金仕达视图附件FTP远程地址
/// </summary>
public string KingstarView_RemotePath { get; set; }
/// <summary>
/// 金仕达视图附件FTP是否启用SSL
/// </summary>
public bool KingstarView_EnableSsl { get; }
/// <summary>
/// 金仕达视图附件FTP登录远程地址的用户名
/// </summary>
public string KingstarView_RemoteUser { get; set; }
/// <summary>
/// 金仕达视图附件FTP登录远程地址的密码
/// </summary>
public string KingstarView_RemotePassword { get; set; }
/// <summary>
/// 金仕达视图附件FTPFTP连接方式是否为被动模式
/// </summary>
public bool KingstarView_FtpUsePassive { get; set; }
/// <summary>
/// 金仕达视图附件本地存放目录
/// </summary>
public string KingstarView_LocalViewAttDir { get; set; }
/// <summary>
/// 金仕达视图附件FTP远程文件服务器存放根路径
/// </summary>
public string KingstarView_RemoteFileRootPath { get; set; }
/// <summary>
/// FDEP收件箱目录
/// </summary>
public string SAC_FDEPInboxPath { get; set; }
/// <summary>
/// FDEP发件箱目录
/// </summary>
public string SAC_FDEPOutboxPath { get; set; }
/// <summary>
/// 子系统发件箱目录,只支持本地系统
/// </summary>
public string SAC_SubSystemOutboxPath { get; set; }
/// <summary>
/// 子系统收件箱目录,只支持本地系统
/// </summary>
public string SAC_SubSystemInboxPath { get; set; }
/// <summary>
/// 金仕达视图链接字符串
/// </summary>
public string KingstarViewConnectionString { get; set; }
/// <summary>
/// 金仕达视图链接名
/// </summary>
public string KingstarViewTableSchema { get; set; }
/// <summary>
/// 证券业报送中定期报告取值模式
/// <para>1=Db;</para>
/// <para>2=Excel模板;</para>
/// <para>3=Db+Excel模板(该方式中涉及百分比汇总计算时仍使用模板中数据)</para>
/// <para>4=金仕达视图(该方式只涉及互换确认书及存续期的数据)</para>
/// <para>5=Db+金仕达视图</para>
/// <para>6=Excel+金仕达视图</para>
/// <para>7=Db+Excel+金仕达视图</para>
/// </summary>
public SAC_ReportDataSourceEnum SAC_ReportDataSource { get; set; }
/// <summary>
/// 是否隔离报备信息
/// </summary>
public bool NeedIsolateSACInfo { get; set; }
/// <summary>
/// 严格的权限验证
/// </summary>
public bool StrictAuthorize { get; set; }
public bool DisablePasswordLogin { get; set; }
/// <summary>
/// 风险对冲累积总盈亏是否统计已过期的场内交易
/// </summary>
public bool RiskAccPnl_SumExpiredExchangeTrades { get; set; }
/// <summary>
/// 收盘配置
/// </summary>
public string SettlementConfig { get; set; }
/// <summary>
/// 用友科目编码
/// </summary>
public string YongYouKeMuCode { get; set; }
/// <summary>
/// 成交首日结算波动率扣除比例
/// </summary>
public string TradeOpenVolOff { get; set; }
/// <summary>
/// 接口审批
/// <para>0:不开启接口审批</para>
/// <para>1:仅使用接口审批</para>
/// <para>2:使用接口审批和系统审批(目前仅控制客户开户管理页面是否显示审批按钮)</para>
/// </summary>
public int InterfaceApprovalMode { get; set; }
/// <summary>
/// 收盘时是否执行数据采集相关逻辑
/// </summary>
public bool UseSettleDataAcquisition { get; set; }
private double _eodVarPvPercent;
/// <summary>
/// EodVar中百分比的默认值;
/// </summary>
public double EodVarPvPercent
{
get { return _eodVarPvPercent.OtcFormatValue(2); }
set
{
if (value > 1)
{
value = 0.99;
}
else if (value <= 0)
{
value = 0.01;
}
_eodVarPvPercent = value;
}
}
/// <summary>
/// 文件上传允许的文件类型(多个类型用'|'分隔),样例:.xlsx|.docx
/// </summary>
public string UploadFileAccepts { get; set; }
/// <summary>
/// 交易定价要素配置(querystring格式)
/// </summary>
public string TradePricingCfg { get; set; }
/// <summary>
/// 是否启用客户名义本金规模
/// </summary>
public bool UseClientStockEqvNotional { get; set; }
/// <summary>
/// 平滑过渡日历处理模式
/// </summary>
public SmoothingDaycountMode SmoothingDaycountMode { get; set; }
/// <summary>
/// 销售 模式(销售人员 ,客户经理)
/// </summary>
public SaleMode SaleMode { get; set; } = SaleMode.SaleMen;
/// <summary>
/// 累计转远期:远期多空和买卖方向赋值配置
/// </summary>
public OptionTypeAndBuySell OptionTypeAndBuySell { get; set; } = OptionTypeAndBuySell.默认;
/// <summary>
/// 远期开仓是否补偿远期价值
/// </summary>
public ForwardValueIsSupplyOrPay ForwardValueIsSupplyOrPay { get; set; } = ForwardValueIsSupplyOrPay.Type1;
/// <summary>
/// 标的资产信息缓存配置
/// </summary>
public string UnderlyingCacheCfg { get; set; }
/// <summary>
/// 是否禁止匿名访问文件(比如App_Docs文件夹中的文件)
/// </summary>
public bool DisableAnonymousAccessFiles { get; set; }
/// <summary>
/// 远期交易价格模式
/// </summary>
public ForwardTradePriceModel ForwardTradePriceModel { get; set; }
/// <summary>
/// 确认成交,是否进行“资金状况”提示
/// </summary>
public bool IsAvailableForClient { get; set; }
/// <summary>
/// 收盘时交易是否自动延期结算
/// </summary>
public bool IsAutoDelaySettlement { get; set; }
/// <summary>
/// (累计期权)使用'杠杆倍数
/// </summary>
public bool AccumulatorShowMultiplier1 { get; set; }
public bool IsTradeCheckInfo { get; set; }
public bool IsPVIncludePrincipal { get; set; }
public bool IsTradeSinglePriceCalcu { get; set; }
/// <summary>
/// 实时风险-跳过特定交易类型的计算
/// </summary>
public string RealtimeRisk_SkipTradeTypes { get; set; }
/// <summary>
/// 持仓使用固定预付金比例计算是否使用期初价格
/// </summary>
public bool EodFixedMarginUseSpotPrice { get; set; }
public string SalesCommissionCalculation { get; set; }
/// <summary>
/// 启用外部API
/// </summary>
public bool ExternalAPIForCustomCalcEnable { get; set; }
/// <summary>
/// 计算自定义交易的api地址
/// <para>目前仅有自定义结构变更和自定义交易计算时会用到</para>
/// <para>接口文档参考&lt;广期自定义交易结算API对接&gt;文件应该在腾讯文档上</para>
/// </summary>
public string ExternalAPIForCustomCalc { get; set; }
/// <summary>
/// 调用外部Api计算自定义交易时的超时时间(秒)
/// <para>目前仅有自定义结构变更和自定义交易计算时会用到</para>
/// <para>接口文档参考&lt;广期自定义交易结算API对接&gt;文件应该在腾讯文档上</para>
/// </summary>
public int ExternalAPIForCustomCalcTimeOut { get; set; }
/// <summary>
/// 收益互换 OA 移动审批状态查询间隔(秒)。
/// </summary>
public int TradeApprovalOaSyncIntervalSeconds { get; set; } = 30;
public bool IsForwardTradeToBuy { get; set; }
/// <summary>
/// 是否需要实时预警
/// </summary>
public bool IsCalcRealtimeWarning { get; set; } = false;
/// <summary>
/// 自定义报送结构类型
/// </summary>
public string CustomStructureTypeSm { get; set; }
/// <summary>
/// 亚式期权观察日是否包含起算日
/// </summary>
public bool AsianOptionObDatesIncludeStartDate { get; set; }
/// <summary>
/// 客户资金表是否要统计其他资金
/// </summary>
public bool IsSumOthersOnClientCash { get; set; }
/// <summary>
/// 是否允许远程访问admin
/// </summary>
public bool AdminEnableRemote { get; set; }
private int _uploadFileSizeLimit = 102400;
/// <summary>
/// 文件上传大小限制(单位KB)
/// </summary>
public int UploadFileSizeLimit
{
get => _uploadFileSizeLimit;
set => _uploadFileSizeLimit = value > 0 ? value : 102400;
}
/// <summary>
/// 对冲交易接口网址
/// </summary>
public string HedgingTradeUrl { get; set; }
/// <summary>
/// 限制用户每分钟可以发送的最大邮件数量,如每分钟内发送的量超过限制,
/// 邮件将停留在发件箱,邮件被延迟到下一分钟,并最终被发送成功
/// </summary>
public int MailMessageRateLimit { get; set; }
/// <summary>
/// 是否支持多币种結算
/// </summary>
public bool SupportMultiCurrency { get; set; }
/// <summary>
/// 是否支持多日历
/// </summary>
public bool SupportMultiCalendar { get; set; }
/// <summary>
/// 监管报告-场外业务持仓表-配置
/// </summary>
public string Supervise_Position { get; set; }
/// <summary>
/// 日终结算时,到期的场内期权持仓自动执行平仓操作
/// </summary>
public bool AutoCloseExpiriedExchangeOptionPosition { get; set; }
/// <summary>
/// 支持专业版雪球
/// </summary>
public bool SuppotSnowballSpecialist { get; set; }
/// <summary>
/// 结算报告累计期权每观察日的了结数量是否包含乘数
/// </summary>
public bool IsSettlementReportAccOptionContainMultiplier { get; set; }
/// <summary>
/// 结算报告配置(querystring格式)
/// </summary>
public string TradeMarketReportCfg { get; set; }
/// <summary>
/// 场内期权波动率类型(Normal:跟随系统波动率模式,ImpliedVol:隐含波动率)
/// </summary>
public ExchangeOptionVolType ExchangeOptionVolType { get; set; }
/// <summary>
/// 是否使用电子章系统对确认书进行自动用印并上传用印文件
/// </summary>
public bool IsAutoSealAndUploadFiles { get; set; } = false;
/// <summary>
/// 电子用印接口地址
/// </summary>
public string SealApi { get; set; } = "";
/// <summary>
/// 电子章用印关键字
/// </summary>
public string SealKeyWord { get; set; } = "";
/// <summary>
/// 确认书生成时是否自动用印
/// </summary>
public bool IsAutoSealAfterGeneratedBook { get; set; } = false;
/// <summary>
/// 收益互换浮动收益端默认为我方收取,并隐藏收支方向
/// </summary>
public bool SwapFloatingIncomeReceiveOnlyMode { get; set; } = false;
/// <summary>
/// 衡泰内证账号
/// </summary>
public string HTAccount { get; set; } = "";
public int ReportFileBeginNumber { get; set; } = 0;
/// <summary>
/// 登录Token过期时间(秒)
/// 注意:此默认值应与appconfig.xml中的配置保持一致
/// </summary>
public int LoginTokenExpireSeconds { get; set; } = 3600 * 10; // 默认10小时
/// <summary>
/// 密码错误次数限制
/// 注意:此默认值应与appconfig.xml中的配置保持一致
/// </summary>
public int PasswordErrorLimit { get; set; } = 5; // 默认5次
/// <summary>
/// 密码错误锁定时间(分钟)
/// 注意:此默认值应与appconfig.xml中的配置保持一致
/// </summary>
public int PasswordErrorLockMinutes { get; set; } = 120; // 默认120分钟
/// <summary>
/// 收盘回调地址
/// </summary>
public string EodExecCallbackUrl { get; set; } = string.Empty;
}
}
}