You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

893 lines
38 KiB
C#

using DS.Module.Core;
using DS.Module.RedisModule;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.Code.Interface;
using DS.WMS.Core.Code.Method;
using DS.WMS.Core.Map.Interface;
using DS.WMS.Core.Map.Method;
using DS.WMS.Core.Sys.Interface;
using DS.WMS.Core.Sys.Method;
using DS.WMS.Core.TaskPlat.Dtos;
using DS.WMS.Core.TaskPlat.Entity;
using DS.WMS.Core.TaskPlat.Interface;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Mapster;
using DS.Module.DjyServiceStatus;
using Microsoft.AspNetCore.Identity;
using DS.WMS.Core.Op.Interface;
using Masuit.Tools;
using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.Sys.Entity;
using HtmlAgilityPack;
using Microsoft.AspNetCore.Mvc;
using Amazon.Runtime.Internal.Util;
using Newtonsoft.Json;
using NLog;
using DS.Module.Core.Helpers;
using System.Text.Json.Nodes;
using LanguageExt.Pipes;
using DS.WMS.Core.Op.Entity;
using Org.BouncyCastle.Asn1.X9;
using DS.WMS.Core.Op.EDI;
using DS.WMS.Core.Sys.Dtos;
using DS.WMS.Core.Code.Dtos;
namespace DS.WMS.Core.TaskPlat.Method
{
/// <summary>
/// 截止时间变更
/// </summary>
public class TaskManageCutDateChangeService: ITaskManageCutDateChangeService
{
private readonly IServiceProvider _serviceProvider;
private readonly ISqlSugarClient db;
private readonly IUser user;
private readonly ISaasDbService saasService;
private readonly ISeaExportService _seaExportService;
private readonly IConfigService _configService;
private readonly IUserService _userService;
private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
const string EMAIL_API_URL = "email_api_url";
public TaskManageCutDateChangeService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
_seaExportService = _serviceProvider.GetRequiredService<ISeaExportService>();
_configService = _serviceProvider.GetRequiredService<IConfigService>();
_userService = _serviceProvider.GetRequiredService<IUserService>();
}
#region 通过任务主键获取截止时间变更详情
/// <summary>
/// 通过任务主键获取截止时间变更详情
/// </summary>
/// <param name="taskPkId">截止时间变更任务主键</param>
/// <returns>返回回执</returns>
public async Task<DataResult<List<TaskCutDateChangeShowDto>>> GetInfoByTaskId(long taskPKId)
{
List<TaskCutDateChangeShowDto> list = new List<TaskCutDateChangeShowDto>();
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var queryList = await tenantDb.Queryable<TaskBaseInfo>()
.InnerJoin<TaskCutDateChangeInfo>((a, b) => a.Id == b.TASK_ID)
.Where((a, b) => a.Id == taskPKId)
.Select((a, b) => new { Base = a, Cut = b })
.ToListAsync();
//任务主键{taskPkId}无法获取业务信息
if (queryList.Count == 0)
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId));
var parentIdList = queryList.Select(a => a.Cut.Id).ToList();
var detailList = await tenantDb.Queryable<TaskCutDateChangeDetailInfo>()
.Where(a => parentIdList.Contains(a.P_ID)).ToListAsync();
if (detailList.Count > 0)
{
list = detailList.OrderBy(p => p.MBL_NO).Select(p =>
{
TaskCutDateChangeShowDto model = p.Adapt<TaskCutDateChangeShowDto>();
model.NoticeDate = queryList.FirstOrDefault().Cut.NOTICE_DATE;
model.Carrier = queryList.FirstOrDefault().Cut.CARRIER;
return model;
}).ToList();
}
return DataResult<List<TaskCutDateChangeShowDto>>.Success(list);
}
#endregion
#region 检索对应的订舱订单并保存订舱ID
/// <summary>
/// 检索对应的订舱订单并保存订舱ID
/// </summary>
/// <param name="taskPKId">截止时间变更任务主键</param>
/// <returns>返回回执</returns>
public async Task<DataResult<SeaExportOrderExtension>> SearchAndMarkBookingOrder(long taskPKId)
{
SeaExportOrderExtension orderInfo = null;
try
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var queryList = await tenantDb.Queryable<TaskBaseInfo>()
.InnerJoin<TaskCutDateChangeInfo>((a, b) => a.Id == b.TASK_ID)
.Where((a, b) => a.Id == taskPKId)
.Select((a, b) => new { Base = a, Cut = b })
.ToListAsync();
//任务主键{taskPkId}无法获取业务信息
if (queryList.Count == 0)
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId));
string mblNo = queryList.FirstOrDefault().Base.MBL_NO;
var orderRlt = await _seaExportService.SearchOrderInfo(mblNo);
if (!orderRlt.Succeeded)
{
// 提单号 {0} 检索海运出口订单失败
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseSearchOrderFailMBLNo)), mblNo));
}
orderInfo = orderRlt.Data;
foreach (var item in queryList.Select(a => a.Cut).ToList())
{
item.BOOKING_ID = orderInfo.currOrder.Id;
item.UpdateTime = DateTime.Now;
item.UpdateBy = long.Parse(user.UserId);
item.UpdateUserName = user.UserName;
tenantDb.Updateable<TaskCutDateChangeInfo>(item).UpdateColumns(x => new
{
x.BOOKING_ID,
x.UpdateTime,
x.UpdateBy,
x.UpdateUserName
}).ExecuteCommand();
var list = tenantDb.Queryable<TaskCutDateChangeDetailInfo>().Where(a => a.P_ID == item.Id).ToList();
if (list != null && list.Count > 0)
{
list.ForEach(async p =>
{
if (p.MBL_NO.Equals(item.MBL_NO, StringComparison.OrdinalIgnoreCase))
{
p.BOOKING_ID = orderInfo.currOrder.Id;
p.UpdateTime = DateTime.Now;
p.UpdateBy = long.Parse(user.UserId);
p.UpdateUserName = user.UserName;
await tenantDb.Updateable<TaskCutDateChangeDetailInfo>(p).UpdateColumns(x => new
{
x.BOOKING_ID,
x.UpdateTime,
x.UpdateBy,
x.UpdateUserName
}).ExecuteCommandAsync();
}
});
}
}
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 检索截止时间变更订舱记录 处理异常,原因:{ex.Message}");
return DataResult<SeaExportOrderExtension>.FailedData(orderInfo,$"检索失败,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
return DataResult<SeaExportOrderExtension>.Success(orderInfo);
}
#endregion
#region 自动更新订单的截单日期并转发
/// <summary>
/// 自动更新订单的截单日期并转发
/// </summary>
/// <param name="taskPKId">截止时间变更任务主键</param>
/// <returns>返回回执</returns>
public async Task<DataResult> AutoUpdateOrderCutDateAndTranmitToCustomer(long taskPKId)
{
SeaExportOrderExtension orderInfo = null;
try
{
var queryRlt = await SearchAndMarkBookingOrder(taskPKId);
if (!queryRlt.Succeeded)
{
throw new Exception(queryRlt.Message);
}
orderInfo = queryRlt.Data;
//更新海运出口截单时间
var orderRlt = UpdateBookingOrderCutDate(taskPKId, orderInfo);
//更新舱位的截单时间
var slotRlt = UpdateBookingSlotCutDate(taskPKId, orderInfo);
//如果没有配置批量,则按单票发送邮件
var rlt = await SendEmailToCustomer(taskPKId);
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 推送邮件完成,结果:{JsonConvert.SerializeObject(rlt)}");
}
catch(Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期并转发失败异常,原因:{ex.Message}");
return DataResult.Failed( $"自动更新订单的截单日期并转发失败,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
return DataResult.Successed(string.Empty, MultiLanguageConst.OperationSuccess);
}
#endregion
#region 更新订舱截单时间
/// <summary>
/// 更新订舱截单时间
/// </summary>
/// <param name="taskPKId">任务主键</param>
/// <param name="orderInfo">相关海运出口订舱详情</param>
/// <returns>返回回执</returns>
private async Task<DataResult> UpdateBookingOrderCutDate(long taskPKId, SeaExportOrderExtension orderInfo)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
try
{
var queryList = await tenantDb.Queryable<TaskBaseInfo>()
.InnerJoin<TaskCutDateChangeInfo>((a, b) => a.Id == b.TASK_ID)
.Where((a, b) => a.Id == taskPKId)
.Select((a, b) => new { Base = a, Cut = b })
.ToListAsync();
//任务主键{taskPkId}无法获取业务信息
if (queryList.Count == 0)
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId));
List<long> ids = new List<long> { orderInfo.currOrder.Id };
var cutBase = queryList.FirstOrDefault().Cut;
var cutDetail = await tenantDb.Queryable<TaskCutDateChangeDetailInfo>().FirstAsync(a => a.P_ID == cutBase.Id);
if (orderInfo.splitOrMergeFlag == 1)
{
if (orderInfo.otherOrderList.Count > 0)
ids.AddRange(orderInfo.otherOrderList.Select(a => a.Id).ToList());
Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} MBLNO={cutDetail.MBL_NO} 检索海运出口订单匹配到拆票信息 ids={string.Join(",", ids.ToArray())}");
}
foreach (var id in ids)
{
StringBuilder doBuilder = new StringBuilder();
var bookingInfo = await tenantDb.Queryable<SeaExport>().FirstAsync(a => a.Id == id);
if (bookingInfo != null)
{
if (cutDetail.VGM_CUT.HasValue)
{
doBuilder.Append($"VGM CUT 原:{bookingInfo.VGMCloseDate} 新:{cutDetail.VGM_CUT.Value}");
bookingInfo.VGMCloseDate = cutDetail.VGM_CUT.Value;
}
if (cutDetail.CY_CUTOFF.HasValue)
{
doBuilder.Append($"CY CUT 原:{bookingInfo.ClosingDate} 新:{cutDetail.CY_CUTOFF.Value}");
bookingInfo.ClosingDate = cutDetail.CY_CUTOFF.Value;
}
if (cutDetail.SI_CUTOFF.HasValue)
{
doBuilder.Append($"SI CUT 原:{bookingInfo.CloseDocDate} 新:{cutDetail.SI_CUTOFF.Value}");
bookingInfo.CloseDocDate = cutDetail.SI_CUTOFF.Value;
}
tenantDb.Updateable<SeaExport>(bookingInfo).UpdateColumns(it => new
{
it.VGMCloseDate,
it.ClosingDate,
it.CloseDocDate
}).ExecuteCommand();
Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} id={id} mblno={bookingInfo.MBLNO} 更新订舱完毕 详情 {doBuilder.ToString()}");
}
}
}
catch(Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新订舱异常,原因:{ex.Message}");
return DataResult.Failed($"自动更新订单的截单日期更新订舱,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
return DataResult.Successed(string.Empty, MultiLanguageConst.OperationSuccess);
}
#endregion
#region 更新舱位的截止时间
/// <summary>
/// 更新舱位的截止时间
/// </summary>
/// <param name="taskPKId">任务主键</param>
/// <param name="orderInfo">相关海运出口订舱详情</param>
/// <returns>返回回执</returns>
private async Task<DataResult> UpdateBookingSlotCutDate(long taskPKId, SeaExportOrderExtension orderInfo)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
try
{
var queryList = await tenantDb.Queryable<TaskBaseInfo>()
.InnerJoin<TaskCutDateChangeInfo>((a, b) => a.Id == b.TASK_ID)
.Where((a, b) => a.Id == taskPKId)
.Select((a, b) => new { Base = a, Cut = b })
.ToListAsync();
//任务主键{taskPkId}无法获取业务信息
if (queryList.Count == 0)
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId));
var cutBase = queryList.FirstOrDefault().Cut;
var cutDetail = await tenantDb.Queryable<TaskCutDateChangeDetailInfo>().FirstAsync(a => a.P_ID == cutBase.Id);
var slotOrder = await tenantDb.Queryable<BookingSlotBase>().FirstAsync(a => a.SlotBookingNo == cutBase.MBL_NO);
StringBuilder doBuilder = new StringBuilder();
if (slotOrder != null)
{
if (cutDetail.VGM_CUT.HasValue)
{
doBuilder.Append($"VGM CUT 原:{slotOrder.VGMSubmissionCutDate} 新:{cutDetail.VGM_CUT.Value}");
slotOrder.VGMSubmissionCutDate = cutDetail.VGM_CUT.Value;
}
if (cutDetail.CY_CUTOFF.HasValue)
{
doBuilder.Append($"CY CUT 原:{slotOrder.CYCutDate} 新:{cutDetail.CY_CUTOFF.Value}");
slotOrder.CYCutDate = cutDetail.CY_CUTOFF.Value;
}
if (cutDetail.SI_CUTOFF.HasValue)
{
doBuilder.Append($"SI CUT 原:{slotOrder.SICutDate} 新:{cutDetail.SI_CUTOFF.Value}");
slotOrder.SICutDate = cutDetail.SI_CUTOFF.Value;
}
if (cutDetail.MANIFEST_CUT.HasValue)
{
doBuilder.Append($"MANIFEST CUT 原:{slotOrder.ManifestCutDate} 新:{cutDetail.MANIFEST_CUT.Value}");
slotOrder.ManifestCutDate = cutDetail.MANIFEST_CUT.Value;
}
tenantDb.Updateable<BookingSlotBase>(slotOrder).UpdateColumns(it => new
{
it.VGMSubmissionCutDate,
it.CYCutDate,
it.SICutDate,
it.ManifestCutDate
}).ExecuteCommand();
Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} id={cutBase.Id} mblno={slotOrder.SlotBookingNo} 更新舱位完毕 详情 {doBuilder.ToString()}");
}
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新舱位异常,原因:{ex.Message}");
return DataResult.Failed($"自动更新订单的截单日期更新舱位,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
return DataResult.Successed(string.Empty, MultiLanguageConst.OperationSuccess);
}
#endregion
#region 发送邮件通知给客户
/// <summary>
/// 发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">截止时间变更主键</param>
/// <returns>返回回执</returns>
public async Task<DataResult> SendEmailToCustomer(long taskPKId)
{
return null;
}
#endregion
#region 生成并转发通知邮件
/// <summary>
/// 生成并转发通知邮件
/// </summary>
/// <param name="model"></param>
/// <param name="bookingOrderList"></param>
/// <param name="bookingContactList"></param>
/// <param name="taskBaskInfo"></param>
/// <returns></returns>
[NonAction]
private async Task<TaskManageOrderResultDto> GenerateSendEmail(TaskCutDateChangeInfo model, List<TaskCutDateChangeDetailInfo> rowList, List<SeaExportRes> bookingOrderList, List<BusinessOrderContactRes> bookingContactList)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
//TO 邮件接收人
string toEmail = string.Empty;
//订舱OP的邮箱
string opEmail = string.Empty;
//去重客户联系人的邮箱
toEmail = string.Join(";", bookingContactList.Select(x => x.Email.Trim()).Distinct().ToArray());
List<string> opEmailList = new List<string>();
UserViewModel opUserInfo = null;
bookingOrderList.ForEach(bk =>
{
//获取操作OP的邮箱
if (bk.OperatorId > 0)
{
var opUser = _userService.GetUserInfo(bk.OperatorId.ToString());
if (opUser.Succeeded && opUser.Data != null)
{
if (opUserInfo == null)
opUserInfo = opUser.Data;
if (!string.IsNullOrWhiteSpace(opUserInfo.Email))
{
opEmailList.Add(opUserInfo.Email.Trim());
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取操作OP的邮箱opEmail={opEmail} opid={bk.OperatorId} name={opUserInfo.UserName}");
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取操作OP的邮箱失败opEmail={opUserInfo.Email} opid={bk.OperatorId} name={opUserInfo.UserName}");
}
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 检索操作OP信息失败opid={bk.OperatorId} name={opUserInfo.UserName}");
}
}
//获取客服的邮箱
if (bk.CustomerService > 0)
{
var opUser = _userService.GetUserInfo(bk.CustomerService.ToString());
if (opUser.Succeeded && opUser.Data != null)
{
if (!string.IsNullOrWhiteSpace(opUser.Data.Email))
{
opEmailList.Add(opUser.Data.Email.Trim());
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取客服的邮箱opEmail={opEmail} opid={bk.CustomerService} name={opUser.Data.UserName}");
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取客服的邮箱失败opEmail={opUser.Data.Email} opid={bk.CustomerService} name={opUser.Data.UserName}");
}
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 检索客服信息失败opid={bk.CustomerService} name={opUser.Data.UserName}");
}
}
});
if (opEmailList.Count > 0)
opEmail = string.Join(";", opEmailList.Distinct().ToArray());
string emailTitle = $"{model.MBL_NO} Cut-off Details {model.VESSEL}/{model.VOYNO}/";
if (model.PORTLOAD_AREA.Equals("NORTH_PORT", StringComparison.OrdinalIgnoreCase))
{
emailTitle = $"{model.MBL_NO} 截止时间变更 {model.VESSEL}/{model.VOYNO}/";
}
////提取当前公共邮箱的配置
//DjyUserMailAccount publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.TenantId == UserManager.TENANT_ID && x.ShowName == "PublicSend"
// && x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
//Logger.Log(NLog.LogLevel.Info, $"提取当前公共邮箱的配置完成id={publicMailAccount.Id}");
//if (publicMailAccount == null)
//{
// throw Oops.Oh($"提取公共邮箱配置失败请在用户邮箱账号管理增加配置显示名为PublicSend或者配置个人邮箱");
//}
////获取邮件模板
//var printTemplate = _repPrintTemplate.AsQueryable().Filter(null, true).First(x => x.CateCode.Contains("for_information_cutoff_detail") && x.TenantId == UserManager.TENANT_ID);
//if (printTemplate == null)
//{
// throw Oops.Bah(BookingErrorCode.BOOK115);
//}
CodeUserEmailRes publicMailAccount = new CodeUserEmailRes();
//读取邮件模板并填充数据
string emailHtml = "";//await GenerateSendEmailHtml(model, rowList, bookingOrderList, "", opUserInfo, user.TenantName).GetAwaiter().GetResult();
EmailApiUserDefinedDto emailApiUserDefinedDto = new EmailApiUserDefinedDto
{
SendTo = toEmail,
//CCTo = opEmail,
Title = emailTitle,
Body = emailHtml,
Account = publicMailAccount.MailAccount?.Trim(),
Password = publicMailAccount.Password?.Trim(),
Server = publicMailAccount.SmtpServer?.Trim(),
Port = publicMailAccount.SmtpPort.HasValue ? publicMailAccount.SmtpPort.Value : 465,
UseSSL = publicMailAccount.SmtpSSL.HasValue ? publicMailAccount.SmtpSSL.Value : true,
Attaches = new List<AttachesInfo>()
};
//如果配置了租户参数AUTO_TRANS_EMAIL_OP_CCTO-自动转发是否默认抄送操作=ENABLE发送邮件时自动抄送操作
//DjyTenantParamValueOutput paramConfig = _djyTenantParamService.GetParaCodeWithValue(new[] { "AUTO_TRANS_EMAIL_OP_CCTO" }).GetAwaiter().GetResult().FirstOrDefault();
//if (paramConfig != null && paramConfig.ParaValue.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
//{
// emailApiUserDefinedDto.CCTo = opEmail;
//}
Logger.Log(NLog.LogLevel.Info, $"生成请求邮件参数,结果:{JsonConvert.SerializeObject(emailApiUserDefinedDto)}");
//推送邮件
var emailRlt = await PushEmail(emailApiUserDefinedDto);
Logger.Log(NLog.LogLevel.Info, $"推送邮件完成,结果:{JsonConvert.SerializeObject(emailRlt)}");
if (emailRlt.Succeeded)
{
result.succ = true;
result.msg = "成功";
}
else
{
result.succ = false;
result.msg = emailRlt.Message;
//new EmailNoticeHelper().SendEmailNotice($"taskid={model.TASK_ID} 截止时间变更 转发通知邮件失败", $"taskid={model.TASK_ID} 转发通知邮件失败,原因:{emailRlt.msg}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"失败,原因:{ex.Message}";
//new EmailNoticeHelper().SendEmailNotice($"taskid={model.TASK_ID} 截止时间变更 转发通知邮件失败", $"taskid={model.TASK_ID} 转发通知邮件失败,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
}
return result;
}
#endregion
#region 通过邮件模板生成HTML
/// <summary>
/// 通过邮件模板生成HTML
/// </summary>
/// <param name="model">截止时间变更详情</param>
/// <param name="seaExportRes">海运出口详情</param>
/// <param name="filePath">文件路径</param>
/// <param name="opUserInfo">相关操作OP</param>
/// <param name="tenantName">租户全称</param>
/// <returns>返回HTML字符串邮件正文</returns>
[NonAction]
private async Task<string> GenerateSendEmailHtml(TaskCutDateChangeInfo model, List<TaskCutDateChangeDetailInfo> rowList, SeaExportRes seaExportRes,
string filePath, SysUser opUserInfo, string tenantName,string fileAbsPath)
{
string result = string.Empty;
string baseHtml = string.Empty;
try
{
//var opt = App.GetOptions<PrintTemplateOptions>();
//var dirAbs = opt.basePath;
//if (string.IsNullOrEmpty(dirAbs))
//{
// dirAbs = App.WebHostEnvironment.WebRootPath;
//}
//var fileAbsPath = Path.Combine(dirAbs, filePath);
//_logger.LogInformation($"查找模板文件:{fileAbsPath}");
//if (!File.Exists(fileAbsPath))
//{
// throw Oops.Bah(BookingErrorCode.BOOK115);
//}
baseHtml = File.ReadAllText(fileAbsPath);
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.UserName))
{
baseHtml = baseHtml.Replace("#opname#", opUserInfo.UserName);
}
else
{
baseHtml = baseHtml.Replace("#opname#", "操作");
}
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Email))
{
baseHtml = baseHtml.Replace("#opemail#", opUserInfo.Email);
}
else
{
baseHtml = baseHtml.Replace("#opemail#", "");
}
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Phone))
{
baseHtml = baseHtml.Replace("#optel#", opUserInfo.Phone);
}
else if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Tel))
{
baseHtml = baseHtml.Replace("#optel#", opUserInfo.Tel);
}
else
{
baseHtml = baseHtml.Replace("#optel#", "");
}
if (!string.IsNullOrWhiteSpace(model.MBL_NO))
{
baseHtml = baseHtml.Replace("#BillNo#", model.MBL_NO);
}
else
{
baseHtml = baseHtml.Replace("#BillNo#", "");
}
if (!string.IsNullOrWhiteSpace(model.VESSEL))
{
string s = $"{model.VESSEL}/{model.VOYNO}";
baseHtml = baseHtml.Replace("#VesselVoyno#", s);
}
else
{
baseHtml = baseHtml.Replace("#VesselVoyno#", "");
}
var detailInfo = rowList.FirstOrDefault();
if (detailInfo.SI_CUTOFF.HasValue)
{
baseHtml = baseHtml.Replace("#SICutDate#", detailInfo.SI_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#SICutDate#", "");
}
if (detailInfo.VGM_CUT.HasValue)
{
baseHtml = baseHtml.Replace("#VGMCutDate#", detailInfo.VGM_CUT.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#VGMCutDate#", "");
}
if (detailInfo.CY_CUTOFF.HasValue)
{
baseHtml = baseHtml.Replace("#CYCutDate#", detailInfo.CY_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#CYCutDate#", "");
}
if (detailInfo.VOUCHER_CUT_DATE.HasValue)
{
baseHtml = baseHtml.Replace("#VoucherCutDate#", detailInfo.VOUCHER_CUT_DATE.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#VoucherCutDate#", "");
}
if (detailInfo.CY_OPEN.HasValue)
{
baseHtml = baseHtml.Replace("#CYOpenDate#", detailInfo.CY_OPEN.Value.ToString("yyyy-MM-dd"));
}
else
{
baseHtml = baseHtml.Replace("#CYOpenDate#", "");
}
if (!string.IsNullOrWhiteSpace(detailInfo.REASON))
{
baseHtml = baseHtml.Replace("#Reason#", model.REASON);
}
else
{
baseHtml = baseHtml.Replace("#Reason#", "");
}
if (!string.IsNullOrWhiteSpace(tenantName))
{
baseHtml = baseHtml.Replace("#TenantCompanyName#", tenantName);
}
else
{
baseHtml = baseHtml.Replace("#TenantCompanyName#", "");
}
HtmlDocument html = new HtmlDocument();
html.LoadHtml(baseHtml);
var tableNode = html.DocumentNode.SelectSingleNode(".//table[@id='show-table']");
if (model.PORTLOAD_AREA.Equals("SOUTH_PORT", StringComparison.OrdinalIgnoreCase))
{
if (tableNode != null)
{
StringBuilder tableBuilder = new StringBuilder();
for (int i = 0; i < rowList.Count; i++)
{
tableBuilder.Append($"<tr><td>{rowList[i].MBL_NO}</td><td>{rowList[i].CONTA_NO}</td><td>{rowList[i].LOAD_PORT}</td><td>{(rowList[i].ETB.HasValue ? rowList[i].ETB.Value.ToString("yyyy-MM-dd HH:mm") : "")}</td><td>{(rowList[i].ETD.HasValue ? rowList[i].ETD.Value.ToString("yyyy-MM-dd HH:mm") : "")}</td></tr>");
}
//生成From Vessel的table列表
tableNode.ChildNodes.Add(HtmlNode.CreateNode(tableBuilder.ToString()));
}
}
else
{
var southPNodes = html.DocumentNode.SelectNodes(".//p[@class='south_port']");
foreach (var node in southPNodes)
{
node.Remove();
}
tableNode.RemoveAllChildren();
var colArg = new string[] { "Shipment Number", "Vessel - voyage", "样单截止时间 SI Cut Off", "开港时间 CY Open", "截港时间 CY cut off", "舱单-入港清单截止时间", "MDGF提交截止时间 - 危险品货物", "船代VGM截止时间", "海关放行截止时间(Customs Clearance Deadline)" };
tableNode.ChildNodes.Add(HtmlNode.CreateNode($"<tr><th style=\"text-align: left;\">{(string.Join("</th><th style=\"text-align: left;\">", colArg))}</th></tr>"));
StringBuilder tableBuilder = new StringBuilder();
for (int i = 0; i < rowList.Count; i++)
{
tableBuilder.Append($"<tr><td>{rowList[i].MBL_NO}</td>");
tableBuilder.Append($"<td>{($"{rowList[i].VESSEL}/{rowList[i].VOYNO}")}</td>");
tableBuilder.Append($"<td>{(rowList[i].SI_CUTOFF.HasValue ? rowList[i].SI_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].SI_CUTOFF_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].CY_OPEN.HasValue ? rowList[i].CY_OPEN.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].CY_OPEN_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].CY_CUTOFF.HasValue ? rowList[i].CY_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].CY_CUTOFF_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].MANIFEST_CUT.HasValue ? rowList[i].MANIFEST_CUT.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].MANIFEST_CUT_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].MDGF_CUT.HasValue ? rowList[i].MDGF_CUT.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].MDGF_CUT_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].VGM_CUT.HasValue ? rowList[i].VGM_CUT.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].VGM_CUT_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].CLOSING_DATE.HasValue ? rowList[i].CLOSING_DATE.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].CLOSING_DATE_TXT)}</td>");
tableBuilder.Append("</tr>");
}
//生成From Vessel的table列表
tableNode.ChildNodes.Add(HtmlNode.CreateNode(tableBuilder.ToString()));
}
result = html.DocumentNode.OuterHtml;
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"生成截止时间变更转发邮件正文失败,原因:{ex.Message}");
//提单号 {0} 生成截止时间变更转发邮件正文失败,原因:{1}
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseCutDateTransmitGenerateEmailFail)), model.MBL_NO, ex.Message));
}
return result;
}
#endregion
#region 推送邮件
/// <summary>
/// 推送邮件
/// </summary>
/// <param name="emailApiUserDefinedDto">自定义邮件详情</param>
/// <returns>返回回执</returns>
private async Task<DataResult<string>> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto)
{
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
var emailUrl = _configService.GetConfig(EMAIL_API_URL, long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
if (emailUrl == null)
throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.CurrTenantEmailApiUrlNull)));
emailList.Add(emailApiUserDefinedDto);
DateTime bDate = DateTime.Now;
string res = string.Empty;
var jsonBody = JsonConvert.SerializeObject(emailList, Formatting.Indented, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
Logger.Log(NLog.LogLevel.Info, $"发送邮件请求:{jsonBody}");
try
{
res = RequestHelper.Post(jsonBody, emailUrl);
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"发送邮件异常:{ex.Message}");
return DataResult<string>.Failed(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TransmitEmailFail)), ex.Message));
}
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
Logger.Log(NLog.LogLevel.Info, $"发送邮件返回:{res}");
if (!string.IsNullOrWhiteSpace(res))
{
var respObj = JsonConvert.DeserializeAnonymousType(res, new
{
Success = false,
Message = string.Empty,
Code = -9999,
});
if(respObj.Success)
{
return DataResult<string>.Success(respObj.Message);
}
return DataResult<string>.Failed(respObj.Message);
}
return DataResult<string>.Failed(res);
}
#endregion
}
}