@ -39,35 +39,38 @@ using DS.WMS.Core.Op.EDI;
using DS.WMS.Core.Sys.Dtos ;
using DS.WMS.Core.Code.Dtos ;
using DS.Module.Core.Data ;
using DS.WMS.Core.Op.Entity.TaskInteraction ;
using Microsoft.Extensions.Hosting ;
using Microsoft.AspNetCore.Hosting ;
using Microsoft.Extensions.Logging ;
using DS.WMS.Core.Op.Interface.TaskInteraction ;
using DS.WMS.Core.Op.Method.TaskInteraction ;
namespace DS.WMS.Core.TaskPlat.Method
{
/// <summary>
/// 截止时间变更
/// </summary>
public class TaskManageCutDateChangeService : ITaskManageCutDateChangeService
public class TaskManageCutDateChangeService : TaskManageBaseService< 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 )
private readonly ITaskLogService _logService ;
private readonly ITaskMailService _taskMailService ;
private readonly ITaskAllocationService _taskAllocationService ;
public TaskManageCutDateChangeService ( IUser user , ILogger < TaskManageCutDateChangeService > logger ,
ISaasDbService saasDbService ,
IServiceProvider serviceProvider ,
IWebHostEnvironment environment ) : base ( user , logger , saasDbService , serviceProvider , environment )
{
_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 > ( ) ;
user = serviceProvider . GetRequiredService < IUser > ( ) ;
_seaExportService = serviceProvider . GetRequiredService < ISeaExportService > ( ) ;
_configService = serviceProvider . GetRequiredService < IConfigService > ( ) ;
_userService = serviceProvider . GetRequiredService < IUserService > ( ) ;
_taskMailService = serviceProvider . GetRequiredService < ITaskMailService > ( ) ;
_taskAllocationService = serviceProvider . GetRequiredService < ITaskAllocationService > ( ) ;
}
#region 通过任务主键获取截止时间变更详情
@ -80,7 +83,7 @@ namespace DS.WMS.Core.TaskPlat.Method
{
List < TaskCutDateChangeShowDto > list = new List < TaskCutDateChangeShowDto > ( ) ;
var tenantDb = saas Service. GetBizDbScopeById ( user . TenantId ) ;
var tenantDb = saas Db Service. GetBizDbScopeById ( user . TenantId ) ;
//任务不考虑OrgId,这里去掉
tenantDb . QueryFilter . Clear < IOrgId > ( ) ;
@ -89,7 +92,7 @@ namespace DS.WMS.Core.TaskPlat.Method
. 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 ) ) ;
@ -99,7 +102,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var detailList = await tenantDb . Queryable < TaskCutDateChangeDetailInfo > ( )
. Where ( a = > parentIdList . Contains ( a . P_ID ) ) . ToListAsync ( ) ;
if ( detail List. Count > 0 )
if ( query List. Count > 0 )
{
list = detailList . OrderBy ( p = > p . MBL_NO ) . Select ( p = >
{
@ -127,7 +130,7 @@ namespace DS.WMS.Core.TaskPlat.Method
SeaExportOrderExtension orderInfo = null ;
try
{
var tenantDb = saas Service. GetBizDbScopeById ( user . TenantId ) ;
var tenantDb = saas Db Service. GetBizDbScopeById ( user . TenantId ) ;
//任务不考虑OrgId,这里去掉
tenantDb . QueryFilter . Clear < IOrgId > ( ) ;
@ -198,7 +201,7 @@ namespace DS.WMS.Core.TaskPlat.Method
}
catch ( Exception ex )
{
Logger. Log ( NLog . LogLevel . Info , $"taskPKId={taskPKId} 检索截止时间变更订舱记录 处理异常,原因:{ex.Message}" ) ;
logger. LogError ( $"taskPKId={taskPKId} 检索截止时间变更订舱记录 处理异常,原因:{ex.Message}" ) ;
return DataResult < SeaExportOrderExtension > . FailedData ( orderInfo , $"检索失败,原因:{ex.Message}" , MultiLanguageConst . Operation_Failed ) ;
}
@ -235,14 +238,14 @@ namespace DS.WMS.Core.TaskPlat.Method
var slotRlt = UpdateBookingSlotCutDate ( taskPKId , orderInfo ) ;
//如果没有配置批量,则按单票发送邮件
var rlt = await SendEmailToCustomer ( taskPKId ) ;
//var rlt = await SendEmailToCustomer(taskPKId) ;
Logger . Log ( NLog . LogLevel . Info , $"taskPKId={taskPKId} 推送邮件完成,结果:{JsonConvert.SerializeObject(rlt)}" ) ;
//logger.LogInformation( $"taskPKId={taskPKId} 推送邮件完成,结果:{JsonConvert.SerializeObject(rlt)}");
}
catch ( Exception ex )
{
Logger . Log ( NLog . LogLevel . Info , $"taskPKId={taskPKId} 自动更新订单的截单日期并转发失败异常,原因:{ex.Message}" ) ;
//Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期并转发失败异常,原因:{ex.Message}");
return DataResult . Failed ( $"自动更新订单的截单日期并转发失败,原因:{ex.Message}" , MultiLanguageConst . Operation_Failed ) ;
}
@ -260,7 +263,7 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <returns>返回回执</returns>
private async Task < DataResult > UpdateBookingOrderCutDate ( long taskPKId , SeaExportOrderExtension orderInfo )
{
var tenantDb = saas Service. GetBizDbScopeById ( user . TenantId ) ;
var tenantDb = saas Db Service. GetBizDbScopeById ( user . TenantId ) ;
//任务不考虑OrgId,这里去掉
tenantDb . QueryFilter . Clear < IOrgId > ( ) ;
@ -287,7 +290,7 @@ namespace DS.WMS.Core.TaskPlat.Method
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())}" ) ;
//Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} MBLNO={cutDetail.MBL_NO} 检索海运出口订单匹配到拆票信息 ids={string.Join(",", ids.ToArray())}");
}
foreach ( var id in ids )
@ -325,13 +328,13 @@ namespace DS.WMS.Core.TaskPlat.Method
it . CloseDocDate
} ) . ExecuteCommand ( ) ;
Logger . Log ( NLog . LogLevel . Info , $"截止时间变更主键{taskPKId} id={id} mblno={bookingInfo.MBLNO} 更新订舱完毕 详情 {doBuilder.ToString()}" ) ;
//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}" ) ;
//Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新订舱异常,原因:{ex.Message}");
return DataResult . Failed ( $"自动更新订单的截单日期更新订舱,原因:{ex.Message}" , MultiLanguageConst . Operation_Failed ) ;
}
@ -349,7 +352,7 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <returns>返回回执</returns>
private async Task < DataResult > UpdateBookingSlotCutDate ( long taskPKId , SeaExportOrderExtension orderInfo )
{
var tenantDb = saas Service. GetBizDbScopeById ( user . TenantId ) ;
var tenantDb = saas Db Service. GetBizDbScopeById ( user . TenantId ) ;
//任务不考虑OrgId,这里去掉
tenantDb . QueryFilter . Clear < IOrgId > ( ) ;
@ -410,13 +413,13 @@ namespace DS.WMS.Core.TaskPlat.Method
it . ManifestCutDate
} ) . ExecuteCommand ( ) ;
Logger . Log ( NLog . LogLevel . Info , $"截止时间变更主键{taskPKId} id={cutBase.Id} mblno={slotOrder.SlotBookingNo} 更新舱位完毕 详情 {doBuilder.ToString()}" ) ;
//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}" ) ;
//Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新舱位异常,原因:{ex.Message}");
return DataResult . Failed ( $"自动更新订单的截单日期更新舱位,原因:{ex.Message}" , MultiLanguageConst . Operation_Failed ) ;
}
@ -426,475 +429,302 @@ namespace DS.WMS.Core.TaskPlat.Method
# endregion
#region 发送邮件通知给客户
/// <summary>
/// 发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">截止时间变更主键</param>
/// <param name="taskPKId">起运港未提箱主键</param>
/// <param name="businessTaskMailId">邮件模板主键</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 )
public async Task < DataResult < TaskTransferMsgDto > > InnerSendEmailToCustomer ( long taskPKId , long businessTaskMailId )
{
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 ( ) ) ;
/ *
1 、 先 匹 配 订 单 。 这 里 可 能 关 联 的 是 拆 票 订 单 , 如 果 是 拆 票 订 单 需 要 所 有 拆 票 记 录 都 要 发 邮 件 通 知 )
2 、 有 订 单 , 调 取 任 务 规 则 补 全 相 关 人 ( 如 果 当 票 已 经 有 了 人 员 表 记 录 task_base_allocation 则 不 再 处 理 人 员 )
3 、 调 取 发 送 模 板 。
4 、 填 充 模 板 数 据 。
5 、 发 送 邮 件 。
6 、 成 功 后 置 任 务 为 完 成 状 态 。
* /
string emailTitle = $"{model.MBL_NO} Cut-off Details {model.VESSEL}/{model.VOYNO}/" ;
var tenantDb = saasDbService . GetBizDbScopeById ( user . TenantId ) ;
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);
var entity = tenantDb . Queryable < TaskCutDateChangeInfo > ( ) . Filter ( null , true ) . First ( a = > a . TASK_ID = = taskPKId ) ;
//if (printTemplate == null)
//{
// throw Oops.Bah(BookingErrorCode.BOOK115);
//}
var cutDetail = tenantDb . Queryable < TaskCutDateChangeDetailInfo > ( ) . Filter ( null , true ) . First ( a = > a . P_ID = = entity . Id ) ;
CodeUserEmailRes publicMailAccount = new CodeUserEmailRes ( ) ;
//读取邮件模板并填充数据
string emailHtml = "" ; //await GenerateSendEmailHtml(model, rowList, bookingOrderList, "", opUserInfo, user.TenantName).GetAwaiter().GetResult();
var baseInfo = tenantDb . Queryable < TaskBaseInfo > ( ) . Filter ( null , true ) . First ( a = > a . Id = = taskPKId ) ;
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();
var queryRlt = await _seaExportService . SearchOrderInfo ( entity . MBL_NO ) ;
//if (paramConfig != null && paramConfig.ParaValue.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
//{
// emailApiUserDefinedDto.CCTo = opEmail;
//}
if ( ! queryRlt . Succeeded )
{
logger . LogInformation ( $"匹配订单信息失败 mblno={entity.MBL_NO},原因:{queryRlt.Message}" ) ;
Logger . Log ( NLog . LogLevel . Info , $"生成请求邮件参数,结果:{JsonConvert.SerializeObject(emailApiUserDefinedDto)}" ) ;
return DataResult < TaskTransferMsgDto > . Failed ( $"匹配订单信息失败 mblno={entity.MBL_NO},原因:{queryRlt.Message}" ) ;
}
//推送邮件
var emailRlt = await PushEmail ( emailApiUserDefinedDto ) ;
var taskInfo = cutDetail . Adapt < TaskCutDateChangeShowDto > ( ) ;
Logger . Log ( NLog . LogLevel . Info , $"推送邮件完成,结果:{JsonConvert.SerializeObject(emailRlt)}" ) ;
taskInfo . PortloadArea = entity . PORTLOAD_AREA ;
taskInfo . TenantCompanyName = user . TenantName ;
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());
}
//生成标题
if ( ! string . IsNullOrWhiteSpace ( taskInfo . PortloadArea ) & & taskInfo . PortloadArea . Equals ( "NORTH_PORT" , StringComparison . OrdinalIgnoreCase ) )
{
taskInfo . EmailTitle = $"{taskInfo.MBLNo} 截止时间变更 {taskInfo.Vessel}/{taskInfo.VoyNo}/" ;
}
catch ( Exception ex )
else
{
result . succ = false ;
result . msg = $"失败,原因:{ex.Message}" ;
//new EmailNoticeHelper().SendEmailNotice($"taskid={model.TASK_ID} 截止时间变更 转发通知邮件失败", $"taskid={model.TASK_ID} 转发通知邮件失败,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
taskInfo . EmailTitle = $"{taskInfo.MBLNo} Cut-off Details {taskInfo.Vessel}/{taskInfo.VoyNo}/" ;
}
return result ;
}
# endregion
BusinessTaskMail ? mailConfig = _taskMailService . GetAsync ( businessTaskMailId ) . GetAwaiter ( ) . GetResult ( ) . Data ;
#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
if ( mailConfig = = null )
{
//var opt = App.GetOptions<PrintTemplateOptions>();
//var dirAbs = opt.basePath;
//if (string.IsNullOrEmpty(dirAbs))
//{
// dirAbs = App.WebHostEnvironment.WebRootPath;
//}
await _logService . WriteLogAsync ( new Op . Dtos . TaskInteraction . TaskUpdateRequest
{
BusinessId = taskPKId ,
BusinessType = BusinessType . OceanShippingExport ,
AutoCreateNext = true ,
TaskTypeName = TaskBaseTypeEnum . CUT_MODIFY . ToString ( ) ,
//var fileAbsPath = Path.Combine(dirAbs, filePath);
//_logger.LogInformation($"查找模板文件:{fileAbsPath}");
} , $"未能根据任务配置值获取邮件模板设置" ) ;
//if (!File.Exists(fileAbsPath))
//{
// throw Oops.Bah(BookingErrorCode.BOOK115);
//}
return DataResult < TaskTransferMsgDto > . Failed ( "未能根据任务配置值获取邮件模板设置" ) ;
}
var orderInfo = queryRlt . Data ;
baseHtml = File . ReadAllText ( fileAbsPath ) ;
logger . LogInformation ( $"获取订单详情成功 bookid={orderInfo.currOrder.Id}" ) ;
if ( opUserInfo ! = null & & ! string . IsNullOrWhiteSpace ( opUserInfo . UserName ) )
{
baseHtml = baseHtml . Replace ( "#opname#" , opUserInfo . UserName ) ;
}
else
{
baseHtml = baseHtml . Replace ( "#opname#" , "操作" ) ;
}
DateTime nowDate = DateTime . Now ;
if ( opUserInfo ! = null & & ! string . IsNullOrWhiteSpace ( opUserInfo . Email ) )
{
baseHtml = baseHtml . Replace ( "#opemail#" , opUserInfo . Email ) ;
}
else
{
baseHtml = baseHtml . Replace ( "#opemail#" , "" ) ;
}
List < long > orderIdList = new List < long > { orderInfo . currOrder . Id } ;
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 ( orderInfo . otherOrderList ! = null & & orderInfo . otherOrderList . Count > 0 )
orderIdList . AddRange ( orderInfo . otherOrderList . Select ( t = > t . Id ) . ToList ( ) ) ;
if ( ! string . IsNullOrWhiteSpace ( model . MBL_NO ) )
{
baseHtml = baseHtml . Replace ( "#BillNo#" , model . MBL_NO ) ;
}
else
{
baseHtml = baseHtml . Replace ( "#BillNo#" , "" ) ;
}
//如果是拆票需要处理,处理所以分票记录
if ( orderInfo . currOrder . SplitOrMergeFlag = = 1 )
{
bool isHasAlloc = false ;
if ( ! string . IsNullOrWhiteSpace ( model . VESSEL ) )
{
string s = $"{model.VESSEL}/{model.VOYNO}" ;
baseHtml = baseHtml . Replace ( "#VesselVoyno#" , s ) ;
}
else
foreach ( var id in orderIdList )
{
baseHtml = baseHtml . Replace ( "#VesselVoyno#" , "" ) ;
}
var taskAllocList = tenantDb . Queryable < TaskBaseAllocation > ( ) . Where ( a = > a . TaskId = = taskPKId ) . ToList ( ) ;
var detailInfo = rowList . FirstOrDefa ult( ) ;
var searchAllotUserRlt = _taskAllocationService . GetAllotUserBySeaExportId ( TaskBaseTypeEnum . CUT_MODIFY , id , new TaskFlowDataContext ( ) ) . GetAwaiter ( ) . GetResult ( ) ;
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 ( searchAllotUserRlt . Succeeded & & searchAllotUserRlt . Data ? . Count > 0 )
{
isHasAlloc = true ;
if ( detailInfo . VGM_CUT . HasValue )
{
baseHtml = baseHtml . Replace ( "#VGMCutDate#" , detailInfo . VGM_CUT . Value . ToString ( "yyyy-MM-dd HH:mm" ) ) ;
}
else
{
baseHtml = baseHtml . Replace ( "#VGMCutDate#" , "" ) ;
}
var addUserList = searchAllotUserRlt . Data . GroupJoin ( taskAllocList , l = > l . RecvUserId , r = > r . UserId , ( l , r ) = >
{
if ( r . ToList ( ) . Count = = 0 )
return new { add = true , obl = l } ;
if ( detailInfo . CY_CUTOFF . HasValue )
{
baseHtml = baseHtml . Replace ( "#CYCutDate#" , detailInfo . CY_CUTOFF . Value . ToString ( "yyyy-MM-dd HH:mm" ) ) ;
}
else
{
baseHtml = baseHtml . Replace ( "#CYCutDate#" , "" ) ;
}
return new { add = false , obl = l } ;
} ) . Where ( a = > a . add ) . Select ( a = > a . obl ) . ToList ( ) ;
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 ( addUserList . Count > 0 )
{
//写入
addUserList . ForEach ( b = >
{
var alloc = new TaskBaseAllocation
{
Status = baseInfo . STATUS ,
StatusName = baseInfo . STATUS_NAME ,
TaskId = taskPKId ,
StatusTime = nowDate ,
UserId = b . RecvUserId ,
UserName = b . RecvUserName
} ;
tenantDb . Insertable < TaskBaseAllocation > ( alloc ) . ExecuteCommand ( ) ;
} ) ;
}
}
}
if ( ! string . IsNullOrWhiteSpace ( detailInfo . REASON ) )
{
baseHtml = baseHtml . Replace ( "#Reason#" , model . REASON ) ;
}
else
if ( isHasAlloc & & baseInfo . IS_PUBLIC = = 1 )
{
baseHtml = baseHtml . Replace ( "#Reason#" , "" ) ;
await tenantDb . Updateable < TaskBaseInfo > ( baseInfo ) . UpdateColumns ( x = > new
{
x . IS_PUBLIC
} ) . ExecuteCommandAsync ( ) ;
}
}
else
{
var taskAllocList = tenantDb . Queryable < TaskBaseAllocation > ( ) . Where ( a = > a . TaskId = = taskPKId ) . ToList ( ) ;
if ( ! string . IsNullOrWhiteSpace ( tenantName ) )
if ( taskAllocList . Count = = 0 )
{
baseHtml = baseHtml . Replace ( "#TenantCompanyName#" , tenantName ) ;
}
else
{
baseHtml = baseHtml . Replace ( "#TenantCompanyName#" , "" ) ;
}
var searchAllotUserRlt = _taskAllocationService . GetAllotUserBySeaExportId ( TaskBaseTypeEnum . CUT_MODIFY , orderInfo . currOrder . Id , new TaskFlowDataContext ( ) ) . GetAwaiter ( ) . GetResult ( ) ;
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 )
if ( searchAllotUserRlt . Succeeded & & searchAllotUserRlt . Data ? . Count > 0 )
{
StringBuilder tableBuilder = new StringBuilder ( ) ;
//写入
searchAllotUserRlt . Data . ForEach ( b = >
{
var alloc = new TaskBaseAllocation
{
Status = baseInfo . STATUS ,
StatusName = baseInfo . STATUS_NAME ,
TaskId = taskPKId ,
StatusTime = nowDate ,
UserId = b . RecvUserId ,
UserName = b . RecvUserName
} ;
tenantDb . Insertable < TaskBaseAllocation > ( alloc ) . ExecuteCommand ( ) ;
} ) ;
for ( int i = 0 ; i < rowList . Count ; i + + )
if ( baseInfo . IS_PUBLIC = = 1 )
{
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>" ) ;
}
baseInfo . IS_PUBLIC = 0 ;
//生成From Vessel的table列表
tableNode . ChildNodes . Add ( HtmlNode . CreateNode ( tableBuilder . ToString ( ) ) ) ;
await tenantDb . Updateable < TaskBaseInfo > ( baseInfo ) . UpdateColumns ( x = > new
{
x . IS_PUBLIC
} ) . ExecuteCommandAsync ( ) ;
}
}
}
else
{
var southPNodes = html . DocumentNode . SelectNodes ( ".//p[@class='south_port']" ) ;
}
foreach ( var node in southPNodes )
{
node . Remove ( ) ;
}
TaskTransferMsgDto resultDto = new TaskTransferMsgDto
{
ExcuteDate = nowDate ,
Detail = new List < TaskTransferMsgDataDto > ( )
} ;
tableNode . RemoveAllChildren ( ) ;
Dictionary < long , Tuple < bool , string , string > > dict = new Dictionary < long , Tuple < bool , string , string > > ( ) ;
var colArg = new string [ ] { "Shipment Number" , "Vessel - voyage" , "样单截止时间 SI Cut Off" , "开港时间 CY Open" , "截港时间 CY cut off" , "舱单-入港清单截止时间" , "MDGF提交截止时间 - 危险品货物" , "船代VGM截止时间" , "海关放行截止时间(Customs Clearance Deadline)" } ;
foreach ( var id in orderIdList )
{
TaskTransferMsgDataDto detail = new TaskTransferMsgDataDto
{
BusinessId = id ,
} ;
tableNode . ChildNodes . Add ( HtmlNode . CreateNode ( $"<tr><th style=\" text - align : left ; \ ">{(string.Join(" < / th > < th style = \ "text-align: left;\">" , colArg ) ) } < / th > < / tr > "));
var model = new MailTemplateModel < TaskCutDateChangeShowDto > ( taskInfo )
{
BusinessId = id ,
BusinessType = BusinessType . OceanShippingExport ,
} ;
StringBuilder tableBuilder = new StringBuilder ( ) ;
MailService mailService = new MailService ( serviceProvider ) ;
var result = await mailService . SendAsync ( mailConfig , model ) ;
for ( int i = 0 ; i < rowList . Count ; i + + )
if ( ! result . Succeeded )
{
await _logService . WriteLogAsync ( new Op . Dtos . TaskInteraction . TaskUpdateRequest
{
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>" ) ;
}
BusinessId = taskPKId ,
BusinessType = BusinessType . OceanShippingExport ,
AutoCreateNext = true ,
TaskTypeName = TaskBaseTypeEnum . CUT_MODIFY . ToString ( ) ,
//生成From Vessel的table列表
tableNode . ChildNodes . Add ( HtmlNode . CreateNode ( tableBuilder . ToString ( ) ) ) ;
}
} , result . Message ) ;
//return DataResult.Failed(result.Message);
}
result = html . DocumentNode . OuterHtml ;
detail . Status = result . Succeeded ? "SUCC" : "FAILURE" ;
detail . Message = result . Message ;
detail . MBlNo = entity . MBL_NO ;
resultDto . Detail . Add ( detail ) ;
dict . Add ( id , new Tuple < bool , string , string > ( result . Succeeded , result . Message , entity . MBL_NO ) ) ;
}
catch ( Exception ex )
//如果存在失败记录,不能置完成状态
if ( ! dict . Any ( t = > ! t . Value . Item1 ) )
{
Logger . Log ( NLog . LogLevel . Info , $"生成截止时间变更转发邮件正文失败,原因:{ex.Message}" ) ;
entity . IS_TRANSFER_USER = true ;
entity . LST_TRANSFER_USER_DATE = DateTime . Now ;
entity . LST_STATUS = "SUCC" ;
entity . LST_STATUS_NAME = "发送成功" ;
//提单号 {0} 生成截止时间变更转发邮件正文失败,原因:{1}
throw new Exception ( string . Format ( MultiLanguageConst . GetDescription ( nameof ( MultiLanguageConst . TaskBaseCutDateTransmitGenerateEmailFail ) ) , model . MBL_NO , ex . Message ) ) ;
await tenantDb . Updateable < TaskCutDateChangeInfo > ( entity ) . UpdateColumns ( x = > new
{
x . IS_TRANSFER_USER ,
x . LST_TRANSFER_USER_DATE ,
x . LST_STATUS ,
x . LST_STATUS_NAME
} ) . ExecuteCommandAsync ( ) ;
//发送完邮件,自动标记任务状态为完成
await SetTaskStatus ( taskPKId , TaskBaseTypeEnum . CUT_MODIFY , TaskStatusEnum . Complete , DateTime . Now , null ) ;
}
return result ;
return DataResult< TaskTransferMsgDto > . Success ( resultDto) ;
}
# endregion
#region 推送邮件
#region 发送邮件通知给客户(任务自动机调取)
/// <summary>
/// 推送邮件
/// 发送邮件通知给客户(任务自动机调取)
/// </summary>
/// <param name=" emailApiUserDefinedDto">自定义邮件详情 </param>
/// <param name=" dataContext">数据上下文 </param>
/// <returns>返回回执</returns>
p rivate async Task < DataResult < string > > PushEmail ( EmailApiUserDefinedDto emailApiUserDefinedDto )
p ublic async Task < DataResult < TaskTransferMsgDto > > SendEmailToCustomerTask ( TaskFlowDataContext dataContext )
{
List < EmailApiUserDefinedDto > emailList = new List < EmailApiUserDefinedDto > ( ) ;
var emailUrl = _configService . GetConfig ( EMAIL_API_URL , long . Parse ( user . TenantId ) , false ) . GetAwaiter ( ) . GetResult ( ) ? . Data ? . Value ;
var taskPKId = dataContext . Get < long > ( TaskFlowDataNameConst . TaskPKId ) ;
if ( taskPKId = = 0 )
throw new ArgumentException ( $"缺少参数:{nameof(TaskFlowDataNameConst.TaskPKId)}" ) ;
if ( emailUrl = = null )
throw new Exception ( MultiLanguageConst . GetDescription ( nameof ( MultiLanguageConst . CurrTenantEmailApiUrlNull ) ) ) ;
var businessTaskMailId = dataContext . Get < long > ( $"{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}" ) ;
if ( businessTaskMailId = = 0 )
throw new ArgumentException ( $"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}" ) ;
emailList . Add ( emailApiUserDefinedDto ) ;
DateTime bDate = DateTime . Now ;
string res = string . Empty ;
var jsonBody = JsonConvert . SerializeObject ( emailList , Formatting . Indented , new JsonSerializerSettings
if ( businessTaskMailId = = 0 )
{
NullValueHandling = NullValueHandling . Ignore
} ) ;
await _logService . WriteLogAsync ( new Op . Dtos . TaskInteraction . TaskUpdateRequest
{
BusinessId = taskPKId ,
BusinessType = BusinessType . OceanShippingExport ,
AutoCreateNext = true ,
TaskTypeName = TaskBaseTypeEnum . CUT_MODIFY . ToString ( ) ,
Logger . Log ( NLog . LogLevel . Info , $"发送邮件请求:{jsonBody}" ) ;
} , $"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id) }") ;
try
{
res = RequestHelper . Post ( jsonBody , emailUrl ) ;
return DataResult < TaskTransferMsgDto > . Failed ( $"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}" ) ;
}
catch ( Exception ex )
{
Logger . Log ( NLog . LogLevel . Info , $"发送邮件异常:{ex.Message}" ) ;
return DataResult < string > . Failed ( string . Format ( MultiLanguageConst . GetDescription ( nameof ( MultiLanguageConst . TransmitEmailFail ) ) , ex . Message ) ) ;
}
return await InnerSendEmailToCustomer ( taskPKId , businessTaskMailId ) ;
}
# endregion
DateTime eDate = DateTime . Now ;
TimeSpan ts = eDate . Subtract ( bDate ) ;
var timeDiff = ts . TotalMilliseconds ;
#region 手工发送邮件通知给客户
/// <summary>
/// 手工发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">起运港未提箱任务主键</param>
/// <returns>返回回执</returns>
public async Task < DataResult < TaskTransferMsgDto > > ManualSendEmailToCustomer ( long taskPKId )
{
var paramConfig = _configService . GetConfig ( "CutDateChangeEmailTemplateID" , long . Parse ( user . TenantId ) , false ) . GetAwaiter ( ) . GetResult ( ) ? . Data ? . Value ;
Logger . Log ( NLog . LogLevel . Info , $"发送邮件返回:{res}" ) ;
long businessTaskMailId = 0 ;
if ( ! string . IsNullOrWhiteSpace ( res ) )
if ( ! string . IsNullOrWhiteSpace ( paramConfig ) )
{
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 ) ;
businessTaskMailId = long . Parse ( paramConfig ) ;
}
else
{
return DataResult < TaskTransferMsgDto > . Failed ( $"缺少系统参数参数:截止时间变更邮件模板ID-\tCutDateChangeEmailTemplateID" ) ;
}
return DataResult < string > . Failed ( res ) ;
return await InnerSendEmailToCustomer ( taskPKId , businessTaskMailId ) ;
}
# endregion
}