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.

902 lines
39 KiB
C#

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
using DS.Module.Core.Data;
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);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
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);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
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);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
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);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
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
}
}