从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using YLErp.DBModels.Consts;
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
/// <summary>
|
||||
/// AppConfigService
|
||||
/// </summary>
|
||||
public class AppConfigService : YLBaseService
|
||||
{
|
||||
public AppConfigService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取管理密码
|
||||
/// </summary>
|
||||
public string GetAdminPwd()
|
||||
{
|
||||
return DbContext.AppConfig.Where(n => n.PGroup == ConsAppConfig.System && n.PName == ConsAppConfig.AdminPwd)
|
||||
.Select(n => n.PValue).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证管理密码
|
||||
/// </summary>
|
||||
public bool ValidateAdminPwd(string pwd)
|
||||
{
|
||||
return GetAdminPwd() == pwd;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置管理密码
|
||||
/// </summary>
|
||||
public string ResetAdminPwd()
|
||||
{
|
||||
var config = DbContext.AppConfig.FirstOrDefault(n => n.PGroup == ConsAppConfig.System && n.PName == ConsAppConfig.AdminPwd);
|
||||
if (config == null)
|
||||
{
|
||||
config = new AppConfig
|
||||
{
|
||||
PGroup = ConsAppConfig.System,
|
||||
PName = ConsAppConfig.AdminPwd,
|
||||
CreateTime = DateTime.Now,
|
||||
PType = "string",
|
||||
Remark = "系统管理密码"
|
||||
};
|
||||
}
|
||||
config.PValue = Guid.NewGuid().ToString("N") + Guid.NewGuid().ToString("N");
|
||||
DbContext.SaveChanges();
|
||||
return config.PValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int SaveOtcFormatConfig(string configValue)
|
||||
{
|
||||
var config = DbContext.AppConfig.FirstOrDefault(
|
||||
n => n.PGroup == ConsAppConfig.ProjectConfig && n.PName == ConsAppConfig.OtcFormatConfig);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
config = new AppConfig
|
||||
{
|
||||
PGroup = ConsAppConfig.ProjectConfig,
|
||||
PName = ConsAppConfig.OtcFormatConfig,
|
||||
CreateTime = DateTime.Now,
|
||||
PType = "string",
|
||||
Remark = "OTC格式化配置"
|
||||
};
|
||||
DbContext.AppConfig.Add(config);
|
||||
}
|
||||
|
||||
config.PValue = configValue;
|
||||
|
||||
return DbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public int SaveYLWebApiConfig(string configValue)
|
||||
{
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
var data = db.AppConfig.FirstOrDefault(n => n.PGroup == ConsAppConfig.ProjectConfig && n.PName == ConsAppConfig.YLErpWebUrlConfig);
|
||||
if (data == null)
|
||||
{
|
||||
data = new AppConfig()
|
||||
{
|
||||
PGroup = ConsAppConfig.ProjectConfig,
|
||||
PName = ConsAppConfig.YLErpWebUrlConfig,
|
||||
PValue = configValue,
|
||||
PType = "string",
|
||||
Remark = "YLErp Web服务地址"
|
||||
};
|
||||
db.AppConfig.Add(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果已经存在数据就不更新
|
||||
if (string.IsNullOrEmpty(data.PValue))
|
||||
{
|
||||
data.PValue = configValue;
|
||||
}
|
||||
}
|
||||
return db.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 如果不存在,则添加为新数据,否则更新
|
||||
/// </summary>
|
||||
public int SaveConfig(string pgroup, string pname, string pvalue, string ptype, string remark)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(pgroup))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pgroup));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(pname))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pname));
|
||||
}
|
||||
|
||||
var data = DbContext.AppConfig.FirstOrDefault(n => n.PGroup == pgroup && n.PName == pname);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
data = new AppConfig
|
||||
{
|
||||
CreateTime = DateTime.Now,
|
||||
PGroup = pgroup,
|
||||
PName = pname
|
||||
};
|
||||
DbContext.AppConfig.Add(data);
|
||||
}
|
||||
|
||||
data.PType = ptype;
|
||||
data.Remark = remark;
|
||||
data.PValue = pvalue;
|
||||
|
||||
return DbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
using Autofac;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Newtonsoft.Json;
|
||||
using Org.BouncyCastle.Asn1.Ocsp;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using YieldChain.Commons;
|
||||
using YieldChain.Helpers;
|
||||
using YLErp.Cache;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.Models;
|
||||
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
partial class AppInitializer
|
||||
{
|
||||
readonly InnerAppConfigService configService;
|
||||
|
||||
public AppInitializer()
|
||||
{
|
||||
configService = new InnerAppConfigService();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化项目配置文件
|
||||
/// </summary>
|
||||
public void InitializePsConfig(SmtpConfigHandler smtpConfigHandler)
|
||||
{
|
||||
var items = configService.GetAllDatas().Where(a => a.PGroup == "ProjectConfig").ToArray();
|
||||
var dic = new Dictionary<string, object>();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item.PName) || string.IsNullOrWhiteSpace(item.PValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var pname = item.PName;
|
||||
var index = pname.IndexOf('.');
|
||||
pname = pname.Substring(index + 1).Trim();
|
||||
if ("bool".Equals(item.PType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dic[pname] = "true".Equals(item.PValue, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else
|
||||
{
|
||||
dic[pname] = item.PValue;
|
||||
}
|
||||
}
|
||||
PS.ResetConfig(Newtonsoft.Json.JsonConvert.SerializeObject(dic));
|
||||
|
||||
//邮件发送配置
|
||||
var smptConfig = configService.GetData("ProjectConfig", "Erp.SendMailConfig");
|
||||
if (!string.IsNullOrWhiteSpace(smptConfig?.PValue) && smtpConfigHandler != null)
|
||||
{
|
||||
smtpConfigHandler.ResetConfig(smptConfig.PValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitialRedisConfig()
|
||||
{
|
||||
var cacheConfig =JsonConvert.DeserializeObject<CacheConfig>(configService.GetData("ProjectConfig", "Erp.RedisConfig")?.PValue ?? string.Empty)??new CacheConfig();
|
||||
YLServiceLocator.ServiceCollection.AddYLCache(opt =>
|
||||
{
|
||||
opt.Enable = cacheConfig.Enable;
|
||||
opt.ConnectionString= cacheConfig.ConnectionString;
|
||||
opt.DataBaseNum = cacheConfig.DataBaseNum;
|
||||
opt.CustomPrefix = cacheConfig.CustomPrefix;
|
||||
if (string.IsNullOrEmpty(opt.CustomPrefix))
|
||||
{
|
||||
opt.CustomPrefix = ((int)PS.Config.Company).ToString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string GetOtcFormatConfig()
|
||||
{
|
||||
return configService.GetData(ConsAppConfig.ProjectConfig, ConsAppConfig.OtcFormatConfig)?.PValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化插件
|
||||
/// </summary>
|
||||
public static PluginInfo InitializePlugin(out IContainer container)
|
||||
{
|
||||
container = null;
|
||||
|
||||
var pluginFolder = Environment.GetEnvironmentVariable("AppSettings:PluginFolder");
|
||||
|
||||
if (string.IsNullOrEmpty(pluginFolder))
|
||||
{
|
||||
if (OtcAppContext.MapPath != null)
|
||||
{
|
||||
pluginFolder = OtcAppContext.MapPath("~/App_Plugin");
|
||||
|
||||
if (!Directory.Exists(pluginFolder))
|
||||
{
|
||||
pluginFolder = Path.Combine(AppContext.BaseDirectory, "App_Plugin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var info = new PluginInfo
|
||||
{
|
||||
PluginFolder = pluginFolder
|
||||
};
|
||||
|
||||
if (!Directory.Exists(pluginFolder))
|
||||
{
|
||||
info.LoadMessage = "插件目录不存在!";
|
||||
return info;
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("AppSettings:PluginFolder", pluginFolder);
|
||||
|
||||
//加载并注册插件
|
||||
var iocBuilder = new ContainerBuilder();
|
||||
var dllFiles = Directory.GetFiles(pluginFolder, "YLErp.Plugins.*.dll");
|
||||
|
||||
foreach (var dllFile in dllFiles)
|
||||
{
|
||||
if (dllFile.LastIndexOf(".Abstract.") < 0)
|
||||
{
|
||||
var assembly = Assembly.Load(File.ReadAllBytes(dllFile));
|
||||
iocBuilder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
|
||||
info.LoadMessage += assembly.FullName + ";";
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(info.LoadMessage))
|
||||
{
|
||||
info.LoadMessage = "未加载到任何插件!";
|
||||
}
|
||||
else
|
||||
{
|
||||
info.LoadMessage = "加载插件:" + info.LoadMessage;
|
||||
}
|
||||
|
||||
container = iocBuilder.Build();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 某个配置值
|
||||
/// </summary>
|
||||
/// <param name="groupName"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public string GetConfigValue(string groupName,string key)
|
||||
{
|
||||
return configService.GetValue(groupName, key);
|
||||
}
|
||||
public void SetConfigValue(string groupName, string key,string value,string remark)
|
||||
{
|
||||
configService.AddDataIfNotExists(groupName, key, value,"string", remark,true);
|
||||
configService.SaveChanges();
|
||||
}
|
||||
|
||||
private static void CopyPluginFiles(string srcDirPath, string destDirPath, int depth = 0)
|
||||
{
|
||||
var srcDir = new DirectoryInfo(srcDirPath);
|
||||
var srcDirs = srcDir.GetDirectories();
|
||||
|
||||
if (!Directory.Exists(destDirPath))
|
||||
{
|
||||
Directory.CreateDirectory(destDirPath);
|
||||
}
|
||||
|
||||
var srcFiles = srcDir.GetFiles();
|
||||
|
||||
foreach (FileInfo file in srcFiles)
|
||||
{
|
||||
if (depth == 0 && !file.Name.StartsWith("YLErp.Plugins.", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string destFile = Path.Combine(destDirPath, file.Name);
|
||||
file.CopyTo(destFile, true);
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo subdir in srcDirs)
|
||||
{
|
||||
string destDir = Path.Combine(destDirPath, subdir.Name);
|
||||
CopyPluginFiles(subdir.FullName, destDir, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 内部数据访问类
|
||||
/// </summary>
|
||||
class InnerAppConfigService : YLBaseService
|
||||
{
|
||||
Dictionary<string, AppConfig> configDic;
|
||||
|
||||
public InnerAppConfigService() : base(OptUserInfo.SystemUser)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Dictionary<string, AppConfig> ConfigDic
|
||||
{
|
||||
get
|
||||
{
|
||||
configDic ??= DbContext.AppConfig.ToDictionary(n => GetDicKey(n.PGroup, n.PName), StringComparer.OrdinalIgnoreCase);
|
||||
return configDic;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据
|
||||
/// </summary>
|
||||
public IEnumerable<AppConfig> GetAllDatas()
|
||||
{
|
||||
return ConfigDic.Values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
public AppConfig GetData(string group, string name)
|
||||
{
|
||||
return ConfigDic.TryGetValue(GetDicKey(group, name), out AppConfig appConfig) ? appConfig : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据
|
||||
/// </summary>
|
||||
public string GetValue(string group, string name)
|
||||
{
|
||||
return ConfigDic.TryGetValue(GetDicKey(group, name), out AppConfig appConfig) ? appConfig?.PValue : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加配置数据
|
||||
/// </summary>
|
||||
public void AddData(AppConfig item)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item.PGroup))
|
||||
{
|
||||
throw new ArgumentNullException("item.PGroup");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(item.PName))
|
||||
{
|
||||
throw new ArgumentNullException("item.PName");
|
||||
}
|
||||
|
||||
item.PGroup = item.PGroup.Trim();
|
||||
item.PName = item.PName.Trim();
|
||||
var key = GetDicKey(item.PGroup, item.PName);
|
||||
if (ConfigDic.ContainsKey(key))
|
||||
{
|
||||
throw new ArgumentException("已存在相同主键的数据");
|
||||
}
|
||||
DbContext.AppConfig.Add(item);
|
||||
ConfigDic.Add(key, item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除配置数据
|
||||
/// </summary>
|
||||
public AppConfig RemoveData(string group, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(group))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(group));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
var key = GetDicKey(group.Trim(), name.Trim());
|
||||
if (ConfigDic.TryGetValue(key, out AppConfig config))
|
||||
{
|
||||
DbContext.AppConfig.Remove(config);
|
||||
ConfigDic.Remove(key);
|
||||
return config;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新配置数据
|
||||
/// </summary>
|
||||
public void UpdateData(string group, string name, string newRemark)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(group))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(group));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
var key = GetDicKey(group.Trim(), name.Trim());
|
||||
if (ConfigDic.TryGetValue(key, out AppConfig config))
|
||||
{
|
||||
config.Remark = newRemark;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新配置数据(如果不存在则添加),
|
||||
/// oldItem需要PGroup和PName
|
||||
/// </summary>
|
||||
public void UpdateData(AppConfig oldItem, AppConfig newItem)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(oldItem.PGroup))
|
||||
{
|
||||
throw new ArgumentNullException("oldItem.PGroup");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(oldItem.PName))
|
||||
{
|
||||
throw new ArgumentNullException("oldItem.PName");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(newItem.PGroup))
|
||||
{
|
||||
throw new ArgumentNullException("newItem.PGroup");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(newItem.PName))
|
||||
{
|
||||
throw new ArgumentNullException("newItem.PName");
|
||||
}
|
||||
|
||||
ObjectHelper.TrimPropertyValues(oldItem);
|
||||
ObjectHelper.TrimPropertyValues(newItem);
|
||||
|
||||
var oldKey = GetDicKey(oldItem.PGroup, oldItem.PName);
|
||||
var newKey = GetDicKey(newItem.PGroup, newItem.PName);
|
||||
if (oldKey.Equals(newKey, StringComparison.OrdinalIgnoreCase) && configDic.TryGetValue(oldKey, out oldItem))
|
||||
{
|
||||
UpdateChanges(oldItem, newItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
configDic.Remove(oldKey);
|
||||
configDic[newKey] = newItem;
|
||||
DbContext.AppConfig.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 如果不存在,则添加为新数据
|
||||
/// </summary>
|
||||
public bool AddDataIfNotExists(string pgroup, string pname, string pvalue, string ptype, string remark,bool modify=false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(pgroup))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pgroup));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(pname))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pname));
|
||||
}
|
||||
pgroup = pgroup.Trim();
|
||||
pname = pname.Trim();
|
||||
var key = GetDicKey(pgroup, pname);
|
||||
var appConfig = new AppConfig
|
||||
{
|
||||
PGroup = pgroup,
|
||||
PName = pname,
|
||||
PValue = pvalue,
|
||||
PType = ptype,
|
||||
Remark = remark,
|
||||
CreateTime = DateTime.Now
|
||||
};
|
||||
if (!ConfigDic.ContainsKey(key))
|
||||
{
|
||||
|
||||
DbContext.AppConfig.Add(appConfig);
|
||||
ConfigDic.Add(key, appConfig);
|
||||
return true;
|
||||
}
|
||||
if (modify)
|
||||
{
|
||||
var oldAppconfig = ConfigDic[key];
|
||||
UpdateChanges(oldAppconfig, appConfig);
|
||||
ConfigDic[key] = appConfig;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static string GetDicKey(string group, string name)
|
||||
{
|
||||
return string.Concat(group, "\t\f\t", name);
|
||||
}
|
||||
|
||||
public void SaveChanges()
|
||||
{
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
partial class AppInitializer
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统升级
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 升级配置
|
||||
/// </summary>
|
||||
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", "证券业报送数据源;1=Db;2=Excel模板;3=Db+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.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勾选时生效)");
|
||||
//-----------------------------------------------
|
||||
// 删除不再使用的
|
||||
//-----------------------------------------------
|
||||
RemoveUnUsed(configService);
|
||||
}
|
||||
|
||||
private static void RemoveUnUsed(InnerAppConfigService configService)
|
||||
{
|
||||
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 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
|
||||
});
|
||||
}
|
||||
|
||||
adminDb.SaveChanges();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogFactory.GetLogger("升级字典项").Error(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件模板服务
|
||||
/// </summary>
|
||||
public class EmailTemplateService : YLBaseService
|
||||
{
|
||||
public EmailTemplateService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public EmailTemplateService(YLBaseService baseService) : base(baseService)
|
||||
{
|
||||
}
|
||||
|
||||
public EmailTemplate GetData(string emailType)
|
||||
{
|
||||
return DbContext.EmailTemplate.AsNoTracking().FirstOrDefault(n => n.EmailType == emailType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存数据
|
||||
/// </summary>
|
||||
public virtual int SaveData(EmailTemplate data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(data.EmailType))
|
||||
{
|
||||
throw new ServiceException("缺少邮件类型");
|
||||
}
|
||||
|
||||
var dbmodel = DbContext.EmailTemplate.FirstOrDefault(n => n.EmailType == data.EmailType);
|
||||
|
||||
if (dbmodel == null)
|
||||
{
|
||||
DbContext.EmailTemplate.Add(dbmodel = new EmailTemplate());
|
||||
}
|
||||
|
||||
UpdateChanges(dbmodel, data, "id");
|
||||
|
||||
return DbContext.SaveChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成邮件信息,如果从数据库中取不到模板配置,返回null
|
||||
/// </summary>
|
||||
public MailInfoResultModel GenerateMailInfo(string emailType, MailInfoRequestModel reqModel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(emailType))
|
||||
{
|
||||
throw new ArgumentException("不能为空", nameof(emailType));
|
||||
}
|
||||
|
||||
if (reqModel == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(reqModel));
|
||||
}
|
||||
|
||||
var template = DbContext.EmailTemplate.AsNoTracking().FirstOrDefault(n => n.EmailType == emailType);
|
||||
|
||||
if (template == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return GenerateMailInfo(template, reqModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成邮件信息,如果template为null,返回null
|
||||
/// </summary>
|
||||
public static MailInfoResultModel GenerateMailInfo(EmailTemplate template, MailInfoRequestModel reqModel)
|
||||
{
|
||||
if (template is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (reqModel == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(reqModel));
|
||||
}
|
||||
|
||||
string replace(Match m)
|
||||
{
|
||||
switch (m.Groups[1].Value)
|
||||
{
|
||||
case "客户名称":
|
||||
return reqModel.ClientName;
|
||||
case "交易日期":
|
||||
return reqModel.TradeDate;
|
||||
case "文档编号":
|
||||
return reqModel.DocNumber;
|
||||
case "交易列表":
|
||||
return reqModel.TradeList;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var pattern = @"\{\{(客户名称|交易日期|文档编号|交易列表)\}\}";
|
||||
|
||||
var result = new MailInfoResultModel
|
||||
{
|
||||
IsBodyHtml = template.IsBodyHtml,
|
||||
Title = Regex.Replace(template.TitleTemplate, pattern, replace),
|
||||
Body = Regex.Replace(template.BodyTemplate, pattern, replace)
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 邮件信息请求Model
|
||||
/// </summary>
|
||||
public class MailInfoRequestModel
|
||||
{
|
||||
/// <summary>
|
||||
/// {{客户名称}}
|
||||
/// </summary>
|
||||
public string ClientName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// {{交易日期}}
|
||||
/// </summary>
|
||||
public string TradeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// {{文档编号}}
|
||||
/// </summary>
|
||||
public string DocNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// {{交易列表}}
|
||||
/// </summary>
|
||||
public string TradeList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 邮件信息结果Model
|
||||
/// </summary>
|
||||
public class MailInfoResultModel
|
||||
{
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
public string Body { get; set; } = string.Empty;
|
||||
|
||||
public bool IsBodyHtml { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
using BaseOUDAL;
|
||||
using Newtonsoft.Json;
|
||||
using Org.BouncyCastle.Crypto.Tls;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
using System.Data;
|
||||
using YLErp.Abstract;
|
||||
using YLErp.Commons;
|
||||
using YLErp.Helpers;
|
||||
using YLErp.Model;
|
||||
using YLErp.Modules.ClientModule;
|
||||
using YLErp.Modules.SwapModule;
|
||||
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
public class EtradingRuleService : YLBaseService
|
||||
{
|
||||
KafkaProduceHelper kafkaProduceHelper;
|
||||
public EtradingRuleService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
kafkaProduceHelper = new KafkaProduceHelper();
|
||||
}
|
||||
|
||||
public List<string> ImportExcel(Stream streamIn, out int TotalNum, out int SuccessNum)
|
||||
{
|
||||
int rowIndex = 0;
|
||||
List<string> clientNumbers = new List<string>();
|
||||
var trans = DbContext.Database.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 1);
|
||||
|
||||
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1)
|
||||
{
|
||||
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
|
||||
}
|
||||
|
||||
var table = ds.Tables[0];
|
||||
var reader = new DataRowReader(table);
|
||||
|
||||
rowIndex = 1;
|
||||
TotalNum = table.Rows.Count;
|
||||
var tradePositions = new List<EtradingRule>();
|
||||
foreach (DataRow row in table.Rows.Cast<DataRow>())
|
||||
{
|
||||
rowIndex++;
|
||||
|
||||
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
reader.SetDataRow(row);
|
||||
|
||||
var rule = MapRule(reader);
|
||||
SaveRule(rule);
|
||||
clientNumbers.Add(rule.ClientNumber_0);
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
SuccessNum = TotalNum;
|
||||
trans.Commit();
|
||||
trans.Dispose();
|
||||
return clientNumbers;
|
||||
}
|
||||
catch (ServiceException se)
|
||||
{
|
||||
trans.Rollback();
|
||||
trans.Dispose();
|
||||
if (se.Tag != null) throw;
|
||||
throw new ServiceException($"第{rowIndex}行,发生错误:{se.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
trans.Rollback();
|
||||
trans.Dispose();
|
||||
LogFactory.GetLogger("TRS用簿记账户设置").Error(ex);
|
||||
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private EtradingRule MapRule(DataRowReader reader)
|
||||
{
|
||||
//资金流向 对客客户编号 对客簿记账户 对客清算机构 对冲Broker 对冲簿记账户 对冲清算机构
|
||||
|
||||
var rule = new EtradingRule();
|
||||
//var boundeside = reader.GetString("资金流向", false);
|
||||
rule.BoundSide = BoundSideEnum.南向; //默认南向
|
||||
rule.ClientNumber_0 = reader.GetString("对客客户编号", false);
|
||||
if (string.IsNullOrWhiteSpace(rule.ClientNumber_0))
|
||||
{
|
||||
throw new ServiceException("对客客户编号不能为空");
|
||||
}
|
||||
rule.AssetAccount_0 = reader.GetString("对客簿记账户", false);
|
||||
rule.ClearingAgency_0 = reader.GetString("对客清算机构", false);
|
||||
////rule.ClientNumber_1 = reader.GetString("连接客户编号", false);
|
||||
////rule.AssetAccount_1 = reader.GetString("连接簿记账户", false);
|
||||
////rule.ClearingAgency_1 = reader.GetString("连接清算机构", false);
|
||||
//rule.Trader_2 = reader.GetString("交易员编号", false);
|
||||
//rule.Broker_2 = reader.GetString("资金账户", false);
|
||||
//rule.FundAccount_2 = reader.GetString("资金账户2", false);
|
||||
//rule.AssetAccount_2 = reader.GetString("对冲簿记账户", false);
|
||||
//rule.ClearingAgency_2 = reader.GetString("对冲清算机构", false);
|
||||
return rule;
|
||||
}
|
||||
|
||||
public void SaveRule(EtradingRule rule)
|
||||
{
|
||||
CheckRule(rule);
|
||||
DeleteRule(rule.BoundSide, rule.ClientNumber_0);//删除原来的预设
|
||||
DbContext.Etrading_Rule.Add(rule);//重新保存
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
|
||||
private bool CheckRule(EtradingRule rule)
|
||||
{
|
||||
var clients = DataCacheProvider.GetClientDataSource().AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(rule.ClientNumber_0) && !clients.Any(o => o.Number == rule.ClientNumber_0))
|
||||
{
|
||||
throw new ServiceException("对客端客户不存在");
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(rule.ClientNumber_0))
|
||||
{
|
||||
var client = clients.FirstOrDefault(o => o.Number == rule.ClientNumber_0);
|
||||
rule.BoundSide = client.BoundSide;
|
||||
}
|
||||
else
|
||||
{
|
||||
rule.ClientNumber_0 = string.Empty;
|
||||
}
|
||||
|
||||
//if (!string.IsNullOrEmpty(rule.ClientNumber_1) && !clients.Any(o => o.Number == rule.ClientNumber_1))
|
||||
//{
|
||||
// throw new ServiceException("连接客户编号不存在");
|
||||
//}
|
||||
var assets = DataCacheProvider.GetAssetUnitDataSource().AsQueryable();
|
||||
if (!string.IsNullOrEmpty(rule.AssetAccount_0) && !assets.Any(o => o.Name == rule.AssetAccount_0))
|
||||
{
|
||||
throw new ServiceException("对客簿记账户不存在");
|
||||
}
|
||||
//if (!string.IsNullOrEmpty(rule.AssetAccount_1) && !assets.Any(o => o.Name == rule.AssetAccount_1))
|
||||
//{
|
||||
// throw new ServiceException("连接簿记账户不存在");
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
public string DeleteRule(int id)
|
||||
{
|
||||
var rule = DbContext.Etrading_Rule.Find(id);
|
||||
if (rule != null)
|
||||
{
|
||||
DbContext.Etrading_Rule.Remove(rule);
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
return rule.ClientNumber_0;
|
||||
}
|
||||
public void DeleteRule(BoundSideEnum? BoundSide, string ClientNumber)
|
||||
{
|
||||
if (BoundSide != null)
|
||||
{
|
||||
var rule = new EtradingRule();
|
||||
if (string.IsNullOrEmpty(ClientNumber))
|
||||
{
|
||||
rule = DbContext.Etrading_Rule.FirstOrDefault(o => o.BoundSide == BoundSide && string.IsNullOrEmpty(o.ClientNumber_0));
|
||||
}
|
||||
else
|
||||
{
|
||||
rule = DbContext.Etrading_Rule.FirstOrDefault(o => o.ClientNumber_0 == ClientNumber);
|
||||
}
|
||||
|
||||
if (rule != null)
|
||||
{
|
||||
DbContext.Etrading_Rule.Remove(rule);
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 将最新的费率发送到kafka
|
||||
/// </summary>
|
||||
/// <param name="clientId"></param>
|
||||
/// <param name="kafkaProvider"></param>
|
||||
public void SendEtradingRuleToKafka(string clientNumber)
|
||||
{
|
||||
List<Client> clients = new List<Client>();
|
||||
using (var con = new ClientDBContext())
|
||||
{
|
||||
clients = con.client.AsNoTracking().Where(s => s.ProcessStatus == "已开户").ToList();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(clientNumber))
|
||||
{
|
||||
var client = clients.FirstOrDefault(o => o.Number == clientNumber);
|
||||
if (client!=null)
|
||||
{
|
||||
var asset = GetAssetByClient(clientNumber);
|
||||
var account = new EtradeAccountService(UserInfo).GetEtradeAccount(asset)?.balance_account_trade;
|
||||
SendToKafka(client.id, account);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SendAllEtradingRuleToKafka();
|
||||
}
|
||||
}
|
||||
private string GetAssetByClient(string clientNumber)
|
||||
{
|
||||
var rule= DbContext.Etrading_Rule.FirstOrDefault(x=>x.ClientNumber_0== clientNumber);
|
||||
if (rule==null)
|
||||
{
|
||||
rule = DbContext.Etrading_Rule.FirstOrDefault(x => string.IsNullOrEmpty(x.ClientNumber_0));
|
||||
}
|
||||
return rule?.AssetAccount_0;
|
||||
}
|
||||
|
||||
public List<string> GetClientNumers(string asset)
|
||||
{
|
||||
List<string> numbers=new List<string>();
|
||||
if (string.IsNullOrEmpty(asset))
|
||||
{
|
||||
numbers = DbContext.Etrading_Rule.AsNoTracking().Select(s => s.ClientNumber_0).ToList();
|
||||
return numbers;
|
||||
}
|
||||
var rules = DbContext.Etrading_Rule.Where(x => x.AssetAccount_0 == asset|| string.IsNullOrEmpty(x.AssetAccount_0)).AsNoTracking();
|
||||
numbers = rules.Select(s => s.ClientNumber_0).ToList();
|
||||
return numbers;
|
||||
}
|
||||
public void SendAllEtradingRuleToKafka()
|
||||
{
|
||||
var etradingRules = DbContext.Etrading_Rule.AsNoTracking().ToList();
|
||||
List<Client> clients = new List<Client>();
|
||||
using (var con =new ClientDBContext())
|
||||
{
|
||||
clients= con.client.AsNoTracking().Where(s => s.ProcessStatus == "已开户").ToList();
|
||||
}
|
||||
foreach (var client in clients)
|
||||
{
|
||||
var clientRule = etradingRules.FirstOrDefault(x => x.ClientNumber_0 == client.Number);
|
||||
var asset = GetAssetByClient(client.Number);
|
||||
var account = new EtradeAccountService(UserInfo).GetEtradeAccount(asset)?.balance_account_trade;
|
||||
SendToKafka(client.id, account);
|
||||
}
|
||||
}
|
||||
public void SendToKafka(int clientId, string hedgingAccount)
|
||||
{
|
||||
EtradingRuleKafkaModel etradingRuleKafkaModel = new EtradingRuleKafkaModel();
|
||||
etradingRuleKafkaModel.clientId = clientId;
|
||||
etradingRuleKafkaModel.hedgingAccount = hedgingAccount;
|
||||
kafkaProduceHelper.Produce(Environment.GetEnvironmentVariable("KafkaConfig_HedgingAccountTopic"), JsonConvert.SerializeObject(etradingRuleKafkaModel));
|
||||
}
|
||||
public EtradingRule GetEtradingRuleAccont(BoundSideEnum boundSide, string clientNumer)
|
||||
{
|
||||
var etradingRules = DbContext.Etrading_Rule.AsNoTracking().ToList();
|
||||
var etradingRule = etradingRules.FirstOrDefault(x => x.ClientNumber_0 == clientNumer);
|
||||
if (etradingRule == null)
|
||||
{
|
||||
etradingRule = etradingRules.FirstOrDefault(x => string.IsNullOrEmpty(x.ClientNumber_0) && x.BoundSide == boundSide);
|
||||
}
|
||||
return etradingRule;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
class InitializeSetting
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新系统,默认false
|
||||
/// </summary>
|
||||
public bool UpgradeSystem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加载插件,默认false
|
||||
/// </summary>
|
||||
public bool LoadPlugin { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using YLErp.MailKit;
|
||||
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
public class SmtpConfigExt : SmtpConfig
|
||||
{
|
||||
public IEnumerable<SmtpConfig> OtherUsers { get; set; }
|
||||
|
||||
public SmtpConfigExt Clone()
|
||||
{
|
||||
return (SmtpConfigExt)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Text;
|
||||
using YieldChain.Helpers;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.MailKit;
|
||||
|
||||
namespace YLErp.Modules.AppModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件发送配置处理
|
||||
/// </summary>
|
||||
class SmtpConfigHandler
|
||||
{
|
||||
readonly SmtpConfigExt _config;
|
||||
|
||||
public SmtpConfigHandler(SmtpConfigExt config)
|
||||
{
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置邮件发送配置
|
||||
/// </summary>
|
||||
public void ResetConfig(string configText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(configText)) return;
|
||||
|
||||
var arr = configText.Split(new[] { "[|]" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (arr.Length < 1) return;
|
||||
|
||||
var nv = UrlHelper.ParseQueryString(arr[0]) ?? new NameValueCollection();
|
||||
int.TryParse(nv["port"], out int port);
|
||||
_config.Server = nv["server"];
|
||||
_config.Port = port > 0 ? port : 25;
|
||||
_config.UserName = nv["userName"];
|
||||
_config.Password = nv["password"];
|
||||
_config.EnableSsl = "true".Equals(nv["enableSsl"], StringComparison.OrdinalIgnoreCase);
|
||||
_config.ZipAttach = "true".Equals(nv["zipAttach"], StringComparison.OrdinalIgnoreCase);
|
||||
_config.Receipt = "true".Equals(nv["receipt"], StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (arr.Length < 2) return;
|
||||
|
||||
var otherUsers = new List<SmtpConfig>(arr.Length - 1);
|
||||
|
||||
for (var i = 1; i < arr.Length; i++)
|
||||
{
|
||||
nv = UrlHelper.ParseQueryString(arr[i]);
|
||||
if (nv != null)
|
||||
{
|
||||
otherUsers.Add(new SmtpConfig
|
||||
{
|
||||
UserName = nv["userName"],
|
||||
Password = nv["password"],
|
||||
Receipt = "true".Equals(nv["receipt"], StringComparison.OrdinalIgnoreCase)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_config.OtherUsers = otherUsers.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置邮件发送配置
|
||||
/// </summary>
|
||||
public void ResetConfig(SmtpConfigExt newConfig, bool saveIntoDB)
|
||||
{
|
||||
if (newConfig is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(newConfig));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(newConfig?.Server))
|
||||
{
|
||||
throw new ServiceException("主机不能为空");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(newConfig.UserName) ||
|
||||
newConfig.OtherUsers != null && newConfig.OtherUsers.Any(n => string.IsNullOrWhiteSpace(n.UserName)))
|
||||
{
|
||||
throw new ServiceException("用户不能为空");
|
||||
}
|
||||
|
||||
if (newConfig.OtherUsers != null && newConfig.OtherUsers.Count() + 1 !=
|
||||
newConfig.OtherUsers.Select(n => n.UserName.Trim()).Concat(new[] { newConfig.UserName.Trim() }).ToHashSet(StringComparer.OrdinalIgnoreCase).Count)
|
||||
{
|
||||
throw new ServiceException("用户不能重复");
|
||||
}
|
||||
|
||||
if (saveIntoDB)
|
||||
{
|
||||
var sb = new StringBuilder(300);
|
||||
sb.Append("&server=").Append(newConfig.Server);
|
||||
sb.Append("&port=").Append(newConfig.Port);
|
||||
sb.Append("&userName=").Append(newConfig.UserName);
|
||||
sb.Append("&password=").Append(newConfig.Password);
|
||||
sb.Append("&enableSsl=").Append(newConfig.EnableSsl);
|
||||
sb.Append("&zipAttach=").Append(newConfig.ZipAttach);
|
||||
sb.Append("&receipt=").Append(newConfig.Receipt);
|
||||
|
||||
if (newConfig.OtherUsers != null)
|
||||
{
|
||||
foreach (var u in newConfig.OtherUsers)
|
||||
{
|
||||
sb.Append("[|]");
|
||||
sb.Append("&userName=").Append(u.UserName);
|
||||
sb.Append("&password=").Append(u.Password);
|
||||
sb.Append("&receipt=").Append(u.Receipt);
|
||||
}
|
||||
}
|
||||
|
||||
var context = DbContextFactory.GetYLDbContext();
|
||||
var config = context.AppConfig.FirstOrDefault(n => n.PGroup == ConsAppConfig.ProjectConfig && n.PName == ConsAppConfig.SendMailConfig);
|
||||
if (config == null)
|
||||
{
|
||||
config = new AppConfig
|
||||
{
|
||||
PGroup = ConsAppConfig.ProjectConfig,
|
||||
PName = ConsAppConfig.SendMailConfig,
|
||||
CreateTime = DateTime.Now,
|
||||
PType = "string",
|
||||
Remark = "邮件发送配置(格式:&server=192.168.1.1&port=25&userName=test@test.com&password=123456&enableSsl=false|true)"
|
||||
};
|
||||
}
|
||||
config.PValue = sb.ToString();
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
ObjectHelper.MapValues(_config, newConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
namespace YLErp.Modules.AppModule.UpgradModule
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DbUpdateResInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 脚本文件名(不带扩展名)
|
||||
/// </summary>
|
||||
public string UpKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 版本号
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库
|
||||
/// </summary>
|
||||
public string DbSchema { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"upkey:{UpKey},version:{Version},dbschema:{DbSchema}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DbUpdateDto : DbUpdateResInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新状态,0:未执行,100:执行成功,101:执行失败
|
||||
/// </summary>
|
||||
public int UpState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行成功则填写“成功”,失败则填写异常信息或失败原因
|
||||
/// </summary>
|
||||
public string UpResult { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据库更新请求
|
||||
/// </summary>
|
||||
public class DbUpdateRequest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<string> UpKeyList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据库更新执行结果
|
||||
/// </summary>
|
||||
public class DbUpdateResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 脚本名称 20220414_admin_01
|
||||
/// </summary>
|
||||
public string UpKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新状态,0:未执行,100:执行成功,101:执行失败
|
||||
/// </summary>
|
||||
public int UpState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行成功则填写“成功”,失败则填写异常信息或失败原因
|
||||
/// </summary>
|
||||
public string UpResult { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
using BaseOUDAL;
|
||||
using YLErp.Commons;
|
||||
|
||||
namespace YLErp.Modules.AppModule.UpgradModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库结构及数据升级服务
|
||||
/// </summary>
|
||||
public class DbUpdateService
|
||||
{
|
||||
const int UpState_Fail = -1;
|
||||
const int UpState_Done = 1;
|
||||
const int UpState_Pending = 0;
|
||||
|
||||
const string UpType_DbUpdate = "DbUpdate";
|
||||
const string ResNameSpacePrefix = "YLErp.Resources.DbUpdate.Ver";
|
||||
|
||||
#region----获取资源文件列表----
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源文件列表
|
||||
/// </summary>
|
||||
public static List<DbUpdateDto> GetUpdateList()
|
||||
{
|
||||
var upList = new List<DbUpdateDto>();
|
||||
var assembly = typeof(YLErp.Resources.PlaceHolder).Assembly;
|
||||
|
||||
foreach (var resName in assembly.GetManifestResourceNames())
|
||||
{
|
||||
//YLErp.Resources.DbUpdate.Ver_3._17.prod.sql
|
||||
|
||||
if (!resName.StartsWith(ResNameSpacePrefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var upkey = resName.Substring(ResNameSpacePrefix.Length, resName.Length - ResNameSpacePrefix.Length - 4);
|
||||
var strArr = upkey.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var version = string.Join(".", strArr.Take(strArr.Length - 1).Select(n => n.Substring(1)).ToArray());
|
||||
|
||||
var dto = new DbUpdateDto
|
||||
{
|
||||
UpKey = upkey,
|
||||
Version = version,
|
||||
DbSchema = strArr[^1],
|
||||
UpResult = "未执行"
|
||||
};
|
||||
|
||||
upList.Add(dto);
|
||||
}
|
||||
|
||||
var dic = GetLogs();
|
||||
|
||||
foreach (var dto in upList)
|
||||
{
|
||||
if (dic.TryGetValue(dto.UpKey, out var a))
|
||||
{
|
||||
dto.UpState = a.UpState;
|
||||
dto.UpResult = a.UpResult;
|
||||
}
|
||||
}
|
||||
|
||||
return upList.OrderByDescending(x => x.Version + ".").ThenBy(n => n.DbSchema).ToList();
|
||||
}
|
||||
|
||||
private static Dictionary<string, InnerDbLog> GetLogs()
|
||||
{
|
||||
InnerDbLog[] getLogs(DbSet<SysUpdateLog> dbset)
|
||||
{
|
||||
var startDate = DateTime.Today.AddMonths(-6);
|
||||
|
||||
var baseQry = from a in dbset
|
||||
where a.CreateTime > startDate && a.UpType == UpType_DbUpdate
|
||||
select a;
|
||||
|
||||
var groupQry = from a in baseQry
|
||||
group a by a.UpKey into g
|
||||
select new { id = g.Max(n => n.id) };
|
||||
|
||||
var listQry = from g in groupQry
|
||||
join a in baseQry on g.id equals a.id
|
||||
select new InnerDbLog
|
||||
{
|
||||
UpKey = a.UpKey,
|
||||
UpResult = a.UpResult,
|
||||
UpState = a.UpState
|
||||
};
|
||||
|
||||
return listQry.ToArray();
|
||||
}
|
||||
|
||||
var list = new List<InnerDbLog>(100);
|
||||
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
list.AddRange(getLogs(db.SysUpdateLogs));
|
||||
}
|
||||
|
||||
using (var db = DbContextFactory.GetErpBaseContext())
|
||||
{
|
||||
list.AddRange(getLogs(db.SysUpdateLogs));
|
||||
}
|
||||
|
||||
using (var db = DbContextFactory.GetClientDbContext(OptUserInfo.SystemUser))
|
||||
{
|
||||
list.AddRange(getLogs(db.SysUpdateLogs));
|
||||
}
|
||||
|
||||
return CollectionHelper.ToDictionary2(list, n => n.UpKey, n => n, StringComparer.OrdinalIgnoreCase, useFirst: true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region----执行数据库脚本升级----
|
||||
|
||||
/// <summary>
|
||||
/// 执行数据库脚本升级
|
||||
/// </summary>
|
||||
public static List<DbUpdateResult> ExecuteUpdate(IEnumerable<string> upKeyList, bool onlyUpdateDone)
|
||||
{
|
||||
var resultList = new List<DbUpdateResult>();
|
||||
|
||||
var exelist = upKeyList.OrderBy(n => n.ToLowerInvariant()).ToArray();
|
||||
|
||||
foreach (var upkey in exelist)
|
||||
{
|
||||
var result = InnerExecuteUpdate(upkey, onlyUpdateDone);
|
||||
|
||||
resultList.Add(result);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行单个更新
|
||||
/// </summary>
|
||||
private static DbUpdateResult InnerExecuteUpdate(string upkey, bool onlyUpdateDone)
|
||||
{
|
||||
var result = new DbUpdateResult { UpKey = upkey, UpState = UpState_Fail };
|
||||
|
||||
if (string.IsNullOrEmpty(upkey))
|
||||
{
|
||||
result.UpResult = "upkey是空值";
|
||||
return result;
|
||||
}
|
||||
|
||||
result.UpState = UpState_Pending;
|
||||
|
||||
var sqlText = string.Empty;
|
||||
|
||||
if (onlyUpdateDone)
|
||||
{
|
||||
result.UpState = UpState_Done;
|
||||
result.UpResult = "手动更新为已执行";
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlText = GetResourceContent(upkey);
|
||||
|
||||
if (sqlText == null)
|
||||
{
|
||||
result.UpState = UpState_Fail;
|
||||
result.UpResult = "没有找到升级脚本";
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(sqlText))
|
||||
{
|
||||
sqlText = string.Empty;
|
||||
|
||||
result.UpState = UpState_Done;
|
||||
result.UpResult = "升级脚本为空";
|
||||
}
|
||||
}
|
||||
|
||||
using (var db = getDbContext(upkey))
|
||||
{
|
||||
if (db == null)
|
||||
{
|
||||
result.UpResult = "未从upkey中解析出正确的数据库";
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result.UpState == UpState_Pending)
|
||||
{
|
||||
try
|
||||
{
|
||||
var changes = db.Database.ExecuteSqlRaw(sqlText);
|
||||
|
||||
result.UpState = UpState_Done;
|
||||
result.UpResult = "执行成功,受影响的行数:" + changes;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.UpState = UpState_Fail;
|
||||
result.UpResult = ex.Messages();
|
||||
}
|
||||
}
|
||||
|
||||
var dblog = new SysUpdateLog()
|
||||
{
|
||||
UpKey = upkey,
|
||||
UpType = UpType_DbUpdate,
|
||||
|
||||
UpState = result.UpState,
|
||||
UpResult = result.UpResult,
|
||||
|
||||
CreateTime = DateTime.Now
|
||||
};
|
||||
|
||||
db.SysUpdateLogs.Add(dblog);
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
DBContextBase getDbContext(string upkey)
|
||||
{
|
||||
var index = upkey.LastIndexOf('.');
|
||||
var dbSchema = upkey.Substring(index + 1);
|
||||
|
||||
return (dbSchema?.ToLowerInvariant()) switch
|
||||
{
|
||||
"admin" => DbContextFactory.GetErpBaseContext(),
|
||||
"client" => DbContextFactory.GetClientDbContext(OptUserInfo.SystemUser),
|
||||
"prod" => DbContextFactory.GetYLDbContext(),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 查看数据库脚本升级内容
|
||||
/// </summary>
|
||||
public static string GetUpdateContent(IEnumerable<string> upKeyList)
|
||||
{
|
||||
if (upKeyList is null || !upKeyList.Any())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var sb = StringBuilderPool.Acquire();
|
||||
|
||||
var exelist = upKeyList.OrderBy(n =>
|
||||
{
|
||||
var index = n.LastIndexOf('.');
|
||||
return n.Substring(0, index + 1);
|
||||
}).ToArray();
|
||||
|
||||
foreach (var upkey in exelist)
|
||||
{
|
||||
var sqlText = GetResourceContent(upkey);
|
||||
|
||||
sb.AppendLine("-- -----------------------------------------------------------")
|
||||
.Append("-- V").Append(upkey.Replace("_", "")).AppendLine()
|
||||
.AppendLine("-- -----------------------------------------------------------");
|
||||
|
||||
if (sqlText == null)
|
||||
{
|
||||
sb.Append("-- !!!没有找到升级脚本:").Append(upkey).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(sqlText);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回资源文件内容,如果是null表示资源不存在
|
||||
/// </summary>
|
||||
private static string GetResourceContent(string upkey)
|
||||
{
|
||||
var resName = string.Concat(ResNameSpacePrefix, upkey, ".sql");
|
||||
|
||||
var assembly = typeof(Resources.PlaceHolder).Assembly;
|
||||
|
||||
using var s = assembly.GetManifestResourceStream(resName);
|
||||
|
||||
if (s == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using var sr = new StreamReader(s);
|
||||
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
|
||||
class InnerDbLog
|
||||
{
|
||||
public string UpKey { get; set; }
|
||||
|
||||
public string UpResult { get; set; }
|
||||
|
||||
public int UpState { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user