Files
zszq-trs/YLErpDAL/Modules/MarginModule/MarginParamsImportService.cs
T
2024-05-09 14:06:26 +08:00

425 lines
15 KiB
C#

using System.Data;
using System.Text;
using YLErp.Commons;
using YLErp.Models;
namespace YLErp.Modules.MarginModule
{
/// <summary>
/// 标的预付金计算参数导入服务
/// </summary>
public class MarginParamsImportService : YLBaseService
{
public MarginParamsImportService(OptUserInfo userInfo) : base(userInfo)
{
}
public MarginParamsImportService(YLBaseService baseService) : base(baseService)
{
}
/// <summary>
/// 导入标的数据(Excel)
/// </summary>
public MarginParamsImportResult ImportUnderlying(Stream streamIn)
{
var readResult = ReadData(streamIn, false);
if (readResult.hasError)
{
return new MarginParamsImportResult
{
ResultSet = readResult.dataSet,
ResultMsg = "读取导入数据失败,请检查修改后重新导入"
};
}
var lists = new[] { readResult.marginHis, readResult.volRateHis, readResult.updownHis };
if (!lists.Any(n => n.Count > 0))
{
return new MarginParamsImportResult { ResultSet = readResult.dataSet, ResultMsg = "未读取到任何导入数据" };
}
var sqlBuilderList = new List<StringBuilder>(10) { new StringBuilder(5200) };
var tableName = DbContext.GetTableName<UnderlyingHisData>();
var result = new MarginParamsImportResult { ResultSet = readResult.dataSet };
foreach (var list in lists)
{
if (!list.Any())
{
continue;
}
string valueType = null;
string sheetName = list[0].dataRow.Table.TableName;
switch (sheetName)
{
case "预付金比例":
valueType = nameof(MarginParamModel.MarginRate);
break;
case "Span波动率变动":
valueType = nameof(MarginParamModel.VolatilityRate);
break;
case "Span涨跌幅度":
valueType = nameof(MarginParamModel.UpDownLimit);
break;
}
var groups = list.GroupBy(n => n.code);
foreach (var grp in groups)
{
var items = grp.OrderBy(n => n.date).ToArray();
var minDate = items[0].date;
var maxDate = items[items.Length - 1].date;
var sqlBuilder = sqlBuilderList.Last();
if (sqlBuilder.Length > 5000)
{
sqlBuilderList.Add(sqlBuilder = new StringBuilder(5200));
}
sqlBuilder.AppendFormat("delete from {0} where UnderlyingCode='{1}' and ValueDate>='{2}' and ValueDate<='{3}' and ValueType='{4}';"
, tableName, grp.Key, minDate.ToShortDateString(), maxDate.ToShortDateString(), valueType).AppendLine();
foreach (var item in items)
{
DbContext.UnderlyingHisData.Add(new UnderlyingHisData
{
UnderlyingCode = grp.Key,
ValueType = valueType,
ValueDate = item.date,
Value = item.dvalue,
OptId = UserId,
OptName = UserName,
OptDate = OptDate,
ValueFlag = sheetName != "Span涨跌幅度" || item.isPercent ? "%" : "F"
});
}
}
}
using (var trans = BeginTransaction())
{
foreach (var sb in sqlBuilderList)
{
var sql = sb.ToString();
if (sql.Length > 0)
{
var changes1 = DbContext.Database.ExecuteSqlRaw(sql);
}
}
result.SuccessSum = DbContext.SaveChanges();
UpdateUnderlyingMaringParams(SystemValueDate);
trans.Commit();
}
return result.SetMsg($"成功处理{result.SuccessSum}条");
}
/// <summary>
/// 使用mysql语句执行underlying_manager表中预付金参数的更新
/// </summary>
private int UpdateUnderlyingMaringParams(DateTime maxDate)
{
var maxDateStr = maxDate.ToString("yyyy-MM-dd");
var sql = $@"
update underlying_manager set
MarginRate= (select `Value` end from underlying_hisdata uh
where uh.UnderlyingCode = underlying_manager.UnderlyingCode and uh.ValueDate <= '{maxDateStr}' && uh.ValueType = 'MarginRate'
order by ValueDate desc limit 1),
VolatilityRate= (select case ValueFlag when '%' then CONCAT(TRUNCATE(`Value`*100,2),'%') else TRUNCATE(`Value`,4) end from underlying_hisdata uh
where uh.UnderlyingCode = underlying_manager.UnderlyingCode and uh.ValueDate <= '{maxDateStr}' && uh.ValueType = 'VolatilityRate'
order by ValueDate desc limit 1),
UpDownLimit= (select case ValueFlag when '%' then CONCAT(TRUNCATE(`Value`*100,2),'%') else TRUNCATE(`Value`,4) end from underlying_hisdata uh
where uh.UnderlyingCode = underlying_manager.UnderlyingCode and uh.ValueDate <= '{maxDateStr}' && uh.ValueType = 'UpDownLimit'
order by ValueDate desc limit 1)";
return DbContext.Database.ExecuteSqlRaw(sql);
}
/// <summary>
/// 导入品种数据(Excel)
/// </summary>
public MarginParamsImportResult ImportVariety(Stream streamIn)
{
var readResult = ReadData(streamIn, true);
if (readResult.hasError)
{
return new MarginParamsImportResult
{
ResultSet = readResult.dataSet,
ResultMsg = "读取导入数据失败,请检查修改后重新导入"
};
}
var lists = new[] { readResult.marginHis, readResult.volRateHis, readResult.updownHis };
if (!lists.Any(n => n.Count > 0))
{
return new MarginParamsImportResult { ResultSet = readResult.dataSet, ResultMsg = "未读取到任何导入数据" };
}
var sysDate = SystemValueDate;
var vaDic = DbContext.variety.ToDictionary(n => n.VarietyCode);
var sqlBuilder = new StringBuilder();
var tableName = DbContext.GetTableName<VarietyHisData>();
var result = new MarginParamsImportResult { ResultSet = readResult.dataSet };
foreach (var list in lists)
{
if (!list.Any())
{
continue;
}
string valueType = null;
string sheetName = list[0].dataRow.Table.TableName;
switch (sheetName)
{
case "预付金比例":
valueType = nameof(MarginParamModel.MarginRate);
break;
case "Span波动率变动":
valueType = nameof(MarginParamModel.VolatilityRate);
break;
case "Span涨跌幅度":
valueType = nameof(MarginParamModel.UpDownLimit);
break;
}
var groups = list.GroupBy(n => n.code);
foreach (var grp in groups)
{
var items = grp.OrderBy(n => n.date).ToArray();
if (!vaDic.TryGetValue(grp.Key, out var va))
{
foreach (var item in items)
{
result.FailSum++;
item.dataRow["处理结果"] = "品种信息不存在";
}
continue;
}
result.SuccessSum++;
var minDate = items[0].date;
var maxDate = items[items.Length - 1].date;
sqlBuilder.AppendFormat("delete from {0} where VarietyId={1} and ValueDate>='{2}' and ValueDate<='{3}' and ValueType='{4}';"
, tableName, va.id, minDate.ToShortDateString(), maxDate.ToShortDateString(), valueType).AppendLine();
var index = 0;
foreach (var item in items)
{
if (item.date <= sysDate)
{
index++;
}
DbContext.VarietyHisData.Add(new VarietyHisData
{
VarietyId = va.id,
ValueType = valueType,
ValueDate = item.date,
Value = item.dvalue,
OptId = UserId,
OptName = UserName,
OptDate = OptDate
});
}
//更新品种数据
if (index > 0)
{
ReadModel rm = null;
if (index < items.Length)
{
rm = items[index - 1];
}
else if (!DbContext.VarietyHisData.Any(n => n.VarietyId == va.id && n.ValueDate > maxDate && n.ValueDate <= sysDate && n.ValueType == valueType))
{
rm = items[items.Length - 1];
}
if (rm != null)
{
switch (sheetName)
{
case "预付金比例":
va.Margin = rm.dvalue;
break;
case "Span波动率变动":
va.VolatilityRate = rm.dvalue.ToString("P2");
break;
case "Span涨跌幅度":
va.UpLimit = va.DownLimit = rm.dvalue.ToString("P2");
break;
}
}
}
}
}
if (result.SuccessSum < 1)
{
return result.SetMsg("所有导入数据都未能成功处理");
}
using (var trans = BeginTransaction())
{
var sql = sqlBuilder.ToString();
var changes = DbContext.Database.ExecuteSqlRaw(sql);
changes = DbContext.SaveChanges();
trans.Commit();
}
return result.SetMsg($"成功处理{result.SuccessSum}条,失败{result.FailSum}条");
}
private ReadResult ReadData(Stream streamIn, bool isVariety)
{
streamIn.Position = 0;
var codePropName = isVariety ? "品种代码" : "标的代码";
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn);
var readResult = new ReadResult { dataSet = ds };
var uniqSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (DataTable dt in ds.Tables)
{
List<ReadModel> list = null;
switch (dt.TableName)
{
case "预付金比例":
list = readResult.marginHis;
break;
case "Span波动率变动":
list = readResult.volRateHis;
break;
case "Span涨跌幅度":
list = readResult.updownHis;
break;
default: continue;
}
var reader = new DataRowReader(dt);
dt.Columns.Add("处理结果");
var colCount = dt.Columns.Count;
uniqSet.Clear();
foreach (DataRow row in dt.Rows.Cast<DataRow>())
{
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
{
continue;
}
reader.SetDataRow(row);
try
{
var model = new ReadModel
{
dataRow = row,
code = reader.GetString(codePropName, true).ToUpperInvariant(),
date = reader.GetDate("变动日期", true).Value,
dvalue = reader.GetPercent(dt.TableName, false) ?? 0
};
if (!uniqSet.Add(model.code + "^" + model.date.ToShortDateString()))
{
throw new ServiceException("重复设置");
}
model.dvalue = Math.Abs(model.dvalue);
model.isPercent = reader.GetString("绝对值方式", false) != "是";
list.Add(model);
}
catch (ServiceException sex)
{
readResult.hasError = true;
row[colCount - 1] = sex.Message;
}
}
}
return readResult;
}
class ReadModel
{
public string code;
public DateTime date;
public double dvalue;
public bool isPercent;
public DataRow dataRow;
}
class ReadResult
{
public bool hasError;
public DataSet dataSet;
public List<ReadModel> marginHis { get; private set; }
public List<ReadModel> volRateHis { get; private set; }
public List<ReadModel> updownHis { get; private set; }
public ReadResult()
{
marginHis = new List<ReadModel>();
volRateHis = new List<ReadModel>();
updownHis = new List<ReadModel>();
}
}
}
/// <summary>
///
/// </summary>
public class MarginParamsImportResult
{
public int FailSum { get; set; }
public int SuccessSum { get; set; }
public string ResultMsg { get; set; }
public DataSet ResultSet { get; set; }
internal MarginParamsImportResult SetMsg(string msg)
{
ResultMsg = msg;
return this;
}
}
}