- 在解析线下费率前记录原始值和空值检查结果 - 记录百分比格式识别和转换过程中的详细信息 - 添加解析成功和失败情况的日志输出 - 记录直接解析小数格式的处理过程 - 添加最终设置OfflineRate值的日志记录 - 完善空值情况下的日志输出
414 lines
19 KiB
C#
414 lines
19 KiB
C#
using BaseOUDAL;
|
|
using Org.BouncyCastle.Ocsp;
|
|
using Qdp.Pricing.Library.Base.Utilities;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Linq.Dynamic.Core;
|
|
using YLErp.Helpers;
|
|
using YLErp.Model;
|
|
using YLErp.Office;
|
|
using Newtonsoft.Json;
|
|
using OfficeOpenXml;
|
|
using YieldChain.Commons;
|
|
using YLErp.Abstract;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using YLErp.Cache;
|
|
|
|
namespace YLErp.Modules.SwapModule
|
|
{
|
|
public class SwapRateService : YLBaseService
|
|
{
|
|
IKafkaProduce kafkaProduceHelper;
|
|
public SwapRateService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
kafkaProduceHelper = YLServiceLocator.ServiceProvider.GetService<IKafkaProduce>();
|
|
}
|
|
/// <summary>
|
|
/// 查询阶梯费率
|
|
/// </summary>
|
|
public SearchListResult<SwapRate> SearchList(SwapRateSearchRequest req)
|
|
{
|
|
var predicate = PredicateBuilder.Create<SwapRate>(n => 1 == 1);
|
|
if (req.OptDateStart.HasValue)
|
|
{
|
|
predicate = predicate.And(n => n.opt_time >= req.OptDateStart.Value);
|
|
}
|
|
if (req.OptDateEnd.HasValue)
|
|
{
|
|
predicate = predicate.And(n => n.opt_time <= req.OptDateEnd.Value);
|
|
}
|
|
if (req.ClientIds.Count > 0)
|
|
{
|
|
predicate = predicate.And(n => req.ClientIds.Contains(n.ClientId));
|
|
}
|
|
if (!string.IsNullOrEmpty(req.ClientNumber))
|
|
{
|
|
predicate = predicate.And(x => x.ClientNumber.Contains(req.ClientNumber.Trim()));
|
|
}
|
|
if (req.TakeEffectDate.HasValue)
|
|
{
|
|
predicate = predicate.And(n => n.TakeEffectDate == req.TakeEffectDate);
|
|
}
|
|
if (!string.IsNullOrEmpty(req.OptName))
|
|
{
|
|
predicate = predicate.And(n => n.opt_name == req.OptName);
|
|
}
|
|
var rateQuery = DbContext.swap_rate.Where(predicate);
|
|
var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable();
|
|
if (string.IsNullOrEmpty(req.sidx))
|
|
{
|
|
req.sidx = "create_time";
|
|
req.sord = "desc";
|
|
}
|
|
var retListResult = rateQuery.ToSearchList(req);
|
|
foreach (var item in retListResult.rows)
|
|
{
|
|
var client = clientQuery.FirstOrDefault(x => x.id == item.ClientId);
|
|
item.ClientName = client?.Name;
|
|
}
|
|
return retListResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存互换费率
|
|
/// </summary>
|
|
/// <param name="req"></param>
|
|
/// <exception cref="Exception"></exception>
|
|
public void SaveSwapRate(SwapRate req, IYLCache ylCache)
|
|
{
|
|
var changeClient = DataCacheProvider.GetClientDataSource().GetData(req.ClientId);
|
|
req.ClientNumber = changeClient?.Number;
|
|
req.ClientName = changeClient?.Name;
|
|
ValidateSwapRate(req);
|
|
string changeStr = string.Empty;
|
|
string changeTitle = "新增";
|
|
if (req.id > 0)
|
|
{
|
|
var swapRate = DbContext.swap_rate.Find(req.id);
|
|
if (swapRate == null)
|
|
{
|
|
throw new ServiceException("未找到该阶梯费率");
|
|
}
|
|
var client = DataCacheProvider.GetClientDataSource().GetData(swapRate.ClientId);
|
|
swapRate.ClientNumber = client?.Number;
|
|
swapRate.ClientName = client?.Name;
|
|
var changeList = DataChangeHelper.GetDataChanges(swapRate, req);
|
|
changeStr = changeList.ToJson();
|
|
changeTitle = "编辑";
|
|
swapRate.ClientId = req.ClientId;
|
|
swapRate.ClientNumber = req.ClientNumber;
|
|
swapRate.TakeEffectDate = req.TakeEffectDate;
|
|
swapRate.TempRateIsPercent = req.TempRateIsPercent;
|
|
swapRate.TempRate = req.TempRate;
|
|
swapRate.BaseRate = req.BaseRate;
|
|
swapRate.BaseRateIsPercent = req.BaseRateIsPercent;
|
|
swapRate.DiscountAccDown = req.DiscountAccDown;
|
|
swapRate.DiscountRateIsPercent = req.DiscountRateIsPercent;
|
|
swapRate.DiscountRate = req.DiscountRate;
|
|
// swapRate.FrontDeskCharge = req.FrontDeskCharge;
|
|
// swapRate.FrontDeskChargeIsPercent = req.FrontDeskChargeIsPercent;
|
|
// swapRate.BackDeskCharge = req.BackDeskCharge;
|
|
// swapRate.BackDeskChargeIsPercent = req.BackDeskChargeIsPercent;
|
|
swapRate.OfflineRate = req.OfflineRate;
|
|
swapRate.SetOpt(UserId, UserName);
|
|
|
|
// 盘中修改了阶梯费率,存储到redis中
|
|
ylCache.StringSetWithNoPrefix<string>("TRS:Update:ClientRate:" + swapRate.ClientId, swapRate.id, TimeSpan.FromHours(8));
|
|
}
|
|
else
|
|
{
|
|
req.SetCreator(UserId, UserName);
|
|
req.SetOpt(UserId, UserName);
|
|
DbContext.swap_rate.Add(req);
|
|
}
|
|
DbContext.SaveChanges();
|
|
new SwapRateLogService(UserInfo).AddSwapRateLog(0, req.id, changeTitle, changeStr, null);
|
|
}
|
|
/// <summary>
|
|
/// 校验数据
|
|
/// </summary>
|
|
/// <param name="req"></param>
|
|
/// <exception cref="ServiceException"></exception>
|
|
private void ValidateSwapRate(SwapRate req)
|
|
{
|
|
if (req.BaseRate == null && req.TempRate == null)
|
|
{
|
|
throw new ServiceException("临时费率或基础费率不能为空");
|
|
}
|
|
if (req.DiscountRate.HasValue && req.DiscountAccDown == null)
|
|
{
|
|
throw new ServiceException("优惠累计量下限不能为空");
|
|
}
|
|
if (!req.DiscountRate.HasValue && req.DiscountAccDown.HasValue)
|
|
{
|
|
throw new ServiceException("优惠累计量下限有值的情况,优惠汇率不能为空");
|
|
}
|
|
if (DbContext.swap_rate.Any(x => x.ClientId == req.ClientId && x.id != req.id && x.TakeEffectDate == req.TakeEffectDate))
|
|
{
|
|
throw new ServiceException($"该客户在{req.TakeEffectDate:D}已经存在阶梯费率");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 删除阶梯费率
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <exception cref="Exception"></exception>
|
|
public int DeleteSwapRate(int id)
|
|
{
|
|
var swapRate = DbContext.swap_rate.Find(id);
|
|
if (swapRate == null)
|
|
{
|
|
throw new ServiceException("未找到该阶梯费率");
|
|
}
|
|
DbContext.swap_rate.Remove(swapRate);
|
|
DbContext.SaveChanges();
|
|
return swapRate.ClientId;
|
|
}
|
|
/// <summary>
|
|
/// 获取详细
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ServiceException"></exception>
|
|
public SwapRate GetSwapRate(int id)
|
|
{
|
|
var swapRate = DbContext.swap_rate.Find(id);
|
|
if (swapRate == null)
|
|
{
|
|
throw new ServiceException("未找到该阶梯费率");
|
|
}
|
|
var client = DataCacheProvider.GetClientDataSource().GetData(swapRate.ClientId);
|
|
swapRate.ClientName = client?.Name;
|
|
swapRate.ClientNumber = client?.Number;
|
|
return swapRate;
|
|
}
|
|
/// <summary>
|
|
/// 阶梯费率导入 excel
|
|
/// </summary>
|
|
/// <param name="streamIn">上传的文件</param>
|
|
/// <param name="totalNum">总条数</param>
|
|
/// <param name="successNum">成功条数</param>
|
|
public List<int> ImportSwapRateFromExcel(Stream streamIn, out int totalNum, out int successNum)
|
|
{
|
|
totalNum = 0;
|
|
successNum = 0;
|
|
var rowIndex = 0;
|
|
List<int> clientIds = new List<int>();
|
|
var trans = DbContext.Database.BeginTransaction();
|
|
try
|
|
{
|
|
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 0);
|
|
|
|
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 2)
|
|
{
|
|
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
|
|
}
|
|
var table = ds.Tables[0];
|
|
var reader = new DataRowReaderHelper(table);
|
|
rowIndex = 1;
|
|
totalNum = table.Rows.Count - rowIndex;
|
|
var clientList = DataCacheProvider.GetClientDataSource().AsQueryable().ToList();
|
|
foreach (var row in table.Rows.Cast<DataRow>().Skip(rowIndex))
|
|
{
|
|
rowIndex++;
|
|
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
|
|
{
|
|
totalNum--;
|
|
continue;
|
|
}
|
|
reader.SetDataRow(row, rowIndex);
|
|
var swapRate = new SwapRate();
|
|
swapRate.ClientNumber = reader.GetString("客户编号", true);
|
|
swapRate.TakeEffectDate = reader.GetDate("生效日期", true).Value;
|
|
var client = clientList.FirstOrDefault(x => x.Number == swapRate.ClientNumber);
|
|
if (client == null)
|
|
{
|
|
throw new ServiceException($"找不到客户编号为{swapRate.ClientNumber}的客户");
|
|
}
|
|
swapRate.ClientId = client.id;
|
|
clientIds.Add(client.id);
|
|
var tempRate = reader.GetString("临时费率");
|
|
if (!string.IsNullOrEmpty(tempRate))
|
|
{
|
|
decimal rate = 0;
|
|
if (tempRate.EndsWith("%"))
|
|
{
|
|
swapRate.TempRateIsPercent = true;
|
|
tempRate = tempRate.Replace("%", "");
|
|
decimal.TryParse(tempRate, out rate);
|
|
rate = rate / 100;
|
|
}
|
|
else
|
|
{
|
|
swapRate.TempRateIsPercent = true;
|
|
decimal.TryParse(tempRate, out rate);
|
|
}
|
|
swapRate.TempRate = rate;
|
|
}
|
|
var baseRate = reader.GetString("基础费率");
|
|
if (!string.IsNullOrEmpty(baseRate))
|
|
{
|
|
decimal rate = 0;
|
|
if (baseRate.EndsWith("%"))
|
|
{
|
|
swapRate.BaseRateIsPercent = true;
|
|
baseRate = baseRate.Replace("%", "");
|
|
decimal.TryParse(baseRate, out rate);
|
|
rate = rate / 100;
|
|
}
|
|
else
|
|
{
|
|
swapRate.BaseRateIsPercent = true;
|
|
decimal.TryParse(baseRate, out rate);
|
|
}
|
|
swapRate.BaseRate = rate;
|
|
}
|
|
var disAccRate = reader.GetString("优惠费率");
|
|
if (!string.IsNullOrEmpty(disAccRate))
|
|
{
|
|
decimal rate = 0;
|
|
if (disAccRate.EndsWith("%"))
|
|
{
|
|
swapRate.DiscountRateIsPercent = true;
|
|
disAccRate = disAccRate.Replace("%", "");
|
|
decimal.TryParse(disAccRate, out rate);
|
|
rate = rate / 100;
|
|
}
|
|
else
|
|
{
|
|
swapRate.DiscountRateIsPercent = true;
|
|
decimal.TryParse(disAccRate, out rate);
|
|
}
|
|
swapRate.DiscountRate = rate;
|
|
}
|
|
//var frontRate = reader.GetString("现券对冲交易费用");
|
|
//if (!string.IsNullOrEmpty(frontRate))
|
|
//{
|
|
// if (frontRate.EndsWith("‱"))
|
|
// {
|
|
// swapRate.FrontDeskChargeIsPercent = true;
|
|
// frontRate = frontRate.Replace("‱", "");
|
|
// }
|
|
|
|
// decimal.TryParse(frontRate, out var rate);
|
|
// swapRate.FrontDeskCharge = rate * 0.0001m;
|
|
//}
|
|
//var backRate = reader.GetString("现券对冲结算费用");
|
|
//if (!string.IsNullOrEmpty(backRate))
|
|
//{
|
|
// if (backRate.EndsWith("‱"))
|
|
// {
|
|
// swapRate.BackDeskChargeIsPercent = true;
|
|
// backRate = backRate.Replace("‱", "");
|
|
// }
|
|
// decimal.TryParse(backRate, out var rate);
|
|
// swapRate.BackDeskCharge = rate * 0.0001m;
|
|
//}
|
|
swapRate.DiscountAccDown = reader.GetDecimal("优惠累计量下限");
|
|
|
|
// 处理线下费率
|
|
var offlineRate = reader.GetString("线下费率");
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,原始线下费率值: '{offlineRate}', IsNullOrEmpty: {string.IsNullOrEmpty(offlineRate)}");
|
|
|
|
if (!string.IsNullOrEmpty(offlineRate))
|
|
{
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,线下费率非空,准备解析: '{offlineRate}'");
|
|
decimal rate = 0;
|
|
if (offlineRate.EndsWith("%"))
|
|
{
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,线下费率是百分比格式: '{offlineRate}'");
|
|
offlineRate = offlineRate.Replace("%", "");
|
|
if (decimal.TryParse(offlineRate, out rate))
|
|
{
|
|
rate /= 100;
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,百分比解析成功: {offlineRate}% -> {rate}");
|
|
}
|
|
else
|
|
{
|
|
LogFactory.GetLogger("导入阶梯费率").Error($"第{rowIndex}行,百分比数值解析失败: '{offlineRate}'");
|
|
rate = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,线下费率不是百分比格式: '{offlineRate}', 尝试直接解析");
|
|
// 如果不是百分比格式,直接尝试解析为小数
|
|
if (!decimal.TryParse(offlineRate, out rate))
|
|
{
|
|
// 解析失败时的处理
|
|
LogFactory.GetLogger("导入阶梯费率").Error($"第{rowIndex}行,线下费率解析失败: '{offlineRate}'");
|
|
rate = 0;
|
|
}
|
|
else
|
|
{
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,直接解析成功: {offlineRate} -> {rate}");
|
|
}
|
|
}
|
|
swapRate.OfflineRate = rate;
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,最终设置OfflineRate为: {rate}");
|
|
}
|
|
else
|
|
{
|
|
LogFactory.GetLogger("导入阶梯费率").Info($"第{rowIndex}行,线下费率为null或空字符串");
|
|
}
|
|
|
|
ValidateSwapRate(swapRate);
|
|
swapRate.SetCreator(UserId, UserName);
|
|
swapRate.SetOpt(UserId, UserName);
|
|
DbContext.swap_rate.Add(swapRate);
|
|
DbContext.SaveChanges();
|
|
new SwapRateLogService(UserInfo).AddSwapRateLog(0, swapRate.id, "新增", null, "导入");
|
|
successNum++;
|
|
}
|
|
trans.Commit();
|
|
trans.Dispose();
|
|
return clientIds;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
trans.Rollback();
|
|
trans.Dispose();
|
|
LogFactory.GetLogger("导入阶梯费率").Error(ex);
|
|
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}");
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 阶梯费率导出
|
|
/// </summary>
|
|
/// <param name="req"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ServiceException"></exception>
|
|
public byte[] exprotSwapRateExcel(SwapRateSearchRequest req)
|
|
{
|
|
//获取数据
|
|
var ret = SearchList(req);
|
|
List<SwapRateExportModel> list = new List<SwapRateExportModel>();
|
|
foreach (var item in ret.rows)
|
|
{
|
|
SwapRateExportModel exportModel = new SwapRateExportModel();
|
|
exportModel.ClientNumber = item.ClientNumber;
|
|
exportModel.ClientName = item.ClientName;
|
|
exportModel.TakeEffectDate = item.TakeEffectDate.OtcFormatDate();
|
|
exportModel.BaseRate = item.BaseRateIsPercent ? item.BaseRate.OtcFormatPercent(4) : item.BaseRate.OtcFormatMoney(true);
|
|
exportModel.TempRate = item.TempRateIsPercent ? item.TempRate.OtcFormatPercent(4) : item.TempRate.OtcFormatMoney(true);
|
|
exportModel.DiscountRate = item.DiscountRateIsPercent ? item.DiscountRate.OtcFormatPercent(4) : item.DiscountRate.OtcFormatMoney(true);
|
|
exportModel.DiscountAccDown = item.DiscountAccDown.OtcFormatMoney(true);
|
|
//exportModel.FrontDeskCharge = item.FrontDeskChargeIsPercent == true ? item.FrontDeskCharge.OtcFormatTenThousandsPercent(4) : item.FrontDeskCharge.OtcFormatMoney(true);
|
|
//exportModel.BackDeskCharge = item.BackDeskChargeIsPercent == true ? item.BackDeskCharge.OtcFormatTenThousandsPercent(4) : item.BackDeskCharge.OtcFormatMoney(true);
|
|
exportModel.OfflineRate = item.OfflineRate.OtcFormatPercent(4);
|
|
list.Add(exportModel);
|
|
}
|
|
var tplFilePath = OtcAppContext.MapPath("/App_Docs");
|
|
var sourceFileName = Path.Combine(tplFilePath, "导出模板", "阶梯费率导出模板.xlsx");
|
|
var modelDict = new Dictionary<string, object>();
|
|
var model = new { list = list };
|
|
modelDict.Add("Sheet1", model);
|
|
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
|
return new ExcelTemplateGenerator().SetTemplateFile(sourceFileName).SetTemplateData(modelDict).Output();
|
|
}
|
|
|
|
}
|
|
}
|