219 lines
10 KiB
C#
219 lines
10 KiB
C#
using BaseOUDAL;
|
||
using NPOI.SS.Formula.Functions;
|
||
using Qdp.Foundation.Utilities;
|
||
using YLErp.DBModels;
|
||
using YLErp.DBModels.Consts;
|
||
using YLErp.DBModels.Enums;
|
||
using YLErp.Model;
|
||
using YLErp.Modules.ApiModule;
|
||
using YLErp.Modules.TradeDalModule;
|
||
using YLErp.Modules.UnderlyingModule;
|
||
using static YLErp.ConsGlobal;
|
||
|
||
namespace YLErp.Modules.TradeModule
|
||
{
|
||
/// <summary>
|
||
/// 交易OA服务
|
||
/// </summary>
|
||
public class TradeOAService : YLBaseService
|
||
{
|
||
private static readonly IYcLogger logger = LogFactory.GetLogger<TradeOAService>();
|
||
|
||
public TradeOAService(OptUserInfo userInfo) : base(userInfo)
|
||
{
|
||
}
|
||
|
||
public TradeOAService(YLBaseService baseService) : base(baseService)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理单个交易的OA提交
|
||
/// </summary>
|
||
/// <param name="tradeId">交易ID</param>
|
||
/// <returns>处理结果</returns>
|
||
public async Task<TradeOAResult> ProcessSingleOAAsync(int tradeId)
|
||
{
|
||
try
|
||
{
|
||
// 获取交易信息
|
||
var trade = DbContext.trade.FirstOrDefault(x => x.id == tradeId);
|
||
if (trade == null)
|
||
{
|
||
return new TradeOAResult { TradeId = tradeId, Success = false, Message = "未找到交易信息" };
|
||
}
|
||
|
||
// 获取交易确认书信息
|
||
var tcr = DbContext.trade_contract_r.Where(t => t.Type == ContractTypeEnum.Trade && t.IsValid && t.TradeId == tradeId)
|
||
.FirstOrDefault();
|
||
trade_contract_document tdoc = null;
|
||
if (tcr != null)
|
||
{
|
||
tdoc = DbContext.trade_contract_document.Where(t => t.Code == tcr.ContractCode && t.Type == tcr.Type).FirstOrDefault();
|
||
}
|
||
|
||
// 将之前的OA记录设置为无效
|
||
var existingOAResults = DbContext.tradeContractOaResult.Where(x => x.trade_id == tradeId && x.is_valid == true).ToList();
|
||
foreach (var existingResult in existingOAResults)
|
||
{
|
||
existingResult.is_valid = false;
|
||
existingResult.SetOpt(UserInfo);
|
||
}
|
||
|
||
|
||
// 创建OA结果记录
|
||
var oaResult = new trade_contract_oa_result
|
||
{
|
||
trade_id = tradeId,
|
||
contract_code = tcr?.ContractCode,
|
||
status = "提交中",
|
||
is_valid = true,
|
||
};
|
||
oaResult.SetOpt(UserInfo);
|
||
DbContext.tradeContractOaResult.Add(oaResult);
|
||
await DbContext.SaveChangesAsync();
|
||
|
||
// 调用OA接口
|
||
var oaResp = await CallOAInterfaceAsync(trade, tcr?.ContractCode, tdoc, oaResult.id);
|
||
if (oaResp != null && oaResp.code == 0)
|
||
{
|
||
oaResult.status = "提交成功";
|
||
oaResult.oa_fileid = oaResp.data?.requestid;
|
||
oaResult.oa_msg = oaResp.data?.msg ?? "提交成功";
|
||
}
|
||
else
|
||
{
|
||
oaResult.status = "提交失败";
|
||
oaResult.oa_msg = oaResp?.data?.msg ?? "OA接口调用失败";
|
||
}
|
||
await DbContext.SaveChangesAsync();
|
||
|
||
return new TradeOAResult { TradeId = tradeId, Success = oaResult.status == "提交成功", Message = oaResult.oa_msg };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
logger.Error($"处理交易ID {tradeId} 的OA时发生错误: {ex.Message}", ex);
|
||
return new TradeOAResult { TradeId = tradeId, Success = false, Message = $"提交OA失败: {ex.Message}" };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调用OA接口
|
||
/// </summary>
|
||
/// <param name="trade">交易信息</param>
|
||
/// <param name="contractCode">合同编号</param>
|
||
/// <param name="tdoc">交易确认书文档</param>
|
||
/// <param name="oaResultId">OA结果记录ID</param>
|
||
/// <returns>是否成功</returns>
|
||
private async Task<GuoLianOAResponse> CallOAInterfaceAsync(trade trade, string contractCode, trade_contract_document tdoc, int oaResultId)
|
||
{
|
||
try
|
||
{
|
||
// 获取OA配置
|
||
var oaConfigSection = AppManager.GetConfiguration().GetSection("oa_confg");
|
||
var baseUrl = oaConfigSection["BaseUrl"];
|
||
var subUrl = oaConfigSection["SubUrl"];
|
||
var systemToken = oaConfigSection["SystemToken"];
|
||
var systemName = oaConfigSection["SystemName"];
|
||
var isNextFlow = oaConfigSection["IsNextFlow"] ?? "0";
|
||
var flowId = oaConfigSection["FlowId"];
|
||
|
||
if (string.IsNullOrEmpty(baseUrl))
|
||
{
|
||
logger.Error("OA接口配置中BaseUrl为空");
|
||
return new GuoLianOAResponse() { code = -1, data = new GuoLianOAData { msg = "OA接口配置中地址为空" } };
|
||
}
|
||
if (string.IsNullOrEmpty(systemToken))
|
||
{
|
||
logger.Error("OA接口配置中SystemToken为空");
|
||
return new GuoLianOAResponse() { code = -1, data = new GuoLianOAData { msg = "OA接口配置中SystemToken为空" } };
|
||
}
|
||
|
||
// 处理附件
|
||
string attachmentBase64 = null;
|
||
string attachmentFileName = null;
|
||
if (tdoc != null && !string.IsNullOrEmpty(tdoc.AbsolutePath))
|
||
{
|
||
try
|
||
{
|
||
if (File.Exists(tdoc.AbsolutePath))
|
||
{
|
||
var fileBytes = await File.ReadAllBytesAsync(tdoc.AbsolutePath);
|
||
attachmentBase64 = Convert.ToBase64String(fileBytes);
|
||
attachmentFileName = Path.GetFileName(tdoc.AbsolutePath);
|
||
logger.Info($"成功读取附件文件:{tdoc.AbsolutePath},文件大小:{fileBytes.Length} 字节");
|
||
}
|
||
else
|
||
{
|
||
logger.Error($"附件文件不存在:{tdoc.AbsolutePath}");
|
||
return new GuoLianOAResponse() { code = -1, data = new GuoLianOAData { msg = "附件文件不存在" } };
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
logger.Error($"读取附件文件失败:{tdoc.AbsolutePath},错误:{ex.Message}", ex);
|
||
return new GuoLianOAResponse() { code = -1, data = new GuoLianOAData { msg = "读取附件文件失败" } };
|
||
}
|
||
}
|
||
|
||
// 构建dataMap
|
||
var dataMap = new
|
||
{
|
||
title = $"固定收益部申请【{contractCode}】TRS交易确认书",
|
||
urgentLevel = "正常",
|
||
applyDate = DateTime.Now.ToString("yyyyMMdd"),
|
||
applicant = UserInfo.UserName,
|
||
applicantComp = "国联民生证券总部",
|
||
contractType = "业务",
|
||
businessType = "金融交易类合同(除股票质押式回购业务部分购回、购回协议)",
|
||
contractSecretLevel = "一般",
|
||
contractUrgentLevel = "一般",
|
||
//去除后缀
|
||
contractName = Path.GetFileNameWithoutExtension(tdoc.FileName),
|
||
isRelatedTransaction = "否",
|
||
partyAType = "企业",
|
||
partyA = trade.ClientName,
|
||
partyBType = "企业",
|
||
partyB = "国联民生证券股份有限公司",
|
||
partyASmsNotify = "否",
|
||
partyBSmsNotify = "否",
|
||
contractAmount = trade.OriginalStockEqvNotional,
|
||
contractBeginDate = trade.StartDate?.ToString("yyyyMMdd"),
|
||
contractEndDate = trade.ExerciseDate?.ToString("yyyyMMdd"),
|
||
currency = "人民币",
|
||
contractSignDate = DateTime.Now.ToString("yyyyMMdd"),
|
||
signIntegrityAgreement = "无需签订",
|
||
contractBackground = $"我司与{trade.ClientName}已完成NAFMII协议签署,并开展TRS交易:{contractCode},参与标的{trade.UnderlyingCode} {trade.UnderlyingName},参与标的数量面额{trade.OriginalStockEqvNotional}元人民币",
|
||
//需要上传接口加附件
|
||
};
|
||
|
||
// 构建查询参数(不包含dataMap,dataMap放在请求体中)
|
||
// 注意:Java后端使用驼峰命名,参数名需与后端@RequestParam注解的名称一致
|
||
var query =
|
||
$"flowId={Uri.EscapeDataString(flowId)}" +
|
||
$"&isNextFlow={Uri.EscapeDataString(isNextFlow ?? string.Empty)}" +
|
||
$"&systemToken={Uri.EscapeDataString(systemToken)}" +
|
||
$"&systemName={Uri.EscapeDataString(systemName ?? string.Empty)}";
|
||
|
||
var requestUrl = subUrl.Contains("?") ? $"{subUrl}&{query}" : $"{subUrl}?{query}";
|
||
logger.Info($"国联OA接口URL: {requestUrl}");
|
||
|
||
// 调用OA接口 (POST请求,dataMap放在请求体中)
|
||
var httpClient = new HttpClientWrap(baseUrl);
|
||
var response = httpClient.PostJson(requestUrl, dataMap, null);
|
||
|
||
logger.Info($"国联OA接口返回: {response}");
|
||
|
||
// 解析响应
|
||
var responseObj = JsonHelper.Deserialize<GuoLianOAResponse>(response);
|
||
return responseObj;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
logger.Error($"调用OA接口时发生异常,交易ID:{trade.id},异常信息:{ex.Message}", ex);
|
||
return new GuoLianOAResponse() { code = -2, data = new GuoLianOAData { msg = $"调用OA接口时发生异常: {ex.Message}" } };
|
||
}
|
||
}
|
||
}
|
||
|
||
} |