修改截止时间变更邮件转发功能

master
jianghaiqing 6 months ago
parent 7e9ed0061a
commit cf303d0be4

@ -3,6 +3,7 @@ using SqlSugar;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -110,5 +111,66 @@ namespace Myshipping.Application
/// 订舱ID /// 订舱ID
/// </summary> /// </summary>
public Nullable<long> BOOKING_ID { get; set; } public Nullable<long> BOOKING_ID { get; set; }
/// <summary>
/// 舱位主键
/// </summary>
public Nullable<long> BOOKING_SLOT_ID { get; set; }
/// <summary>
/// 是否已发通知 1-已发送 0-未发送
/// </summary>
public bool IS_NOTICE { get; set; }
/// <summary>
/// 发送通知时间
/// </summary>
public Nullable<DateTime> NOTICE_DATE { get; set; }
/// <summary>
/// 状态
/// </summary>
public string STATUS { get; set; }
/// <summary>
/// 状态名称
/// </summary>
public string STATUS_NAME { get; set; }
/// <summary>
/// 委托单位名称
/// </summary>
public string CUSTOM_NAME { get; set; }
/// <summary>
/// 原因
/// </summary>
public string REASON { get; set; }
/// <summary>
/// 集装箱号
/// </summary>
public string CONTA_NO { get; set; }
/// <summary>
/// 截补料时间
/// </summary>
public Nullable<DateTime> VOUCHER_CUT_DATE { get; set; }
/// <summary>
/// 装货港
/// </summary>
public string LOAD_PORT { get; set; }
/// <summary>
/// 预计到港
/// </summary>
public Nullable<DateTime> ETD { get; set; }
/// <summary>
/// 预计靠泊
/// </summary>
public Nullable<DateTime> ETB { get; set; }
} }
} }

@ -41,5 +41,29 @@ namespace Myshipping.Application
/// </summary> /// </summary>
public Nullable<DateTime> NOTICE_DATE { get; set; } public Nullable<DateTime> NOTICE_DATE { get; set; }
/// <summary>
/// 订舱ID
/// </summary>
public Nullable<long> BOOKING_ID { get; set; }
/// <summary>
/// 舱位主键
/// </summary>
public Nullable<long> BOOKING_SLOT_ID { get; set; }
/// <summary>
/// 主单号
/// </summary>
public string MBL_NO { get; set; }
/// <summary>
/// 装货港区域 NORTH_PORT-华北港口 SOUTH-华南港口
/// </summary>
public string PORTLOAD_AREA { get; set; }
/// <summary>
/// 原因
/// </summary>
public string REASON { get; set; }
} }
} }

@ -7549,7 +7549,7 @@ namespace Myshipping.Application
order.BOOKINGNO = flowno; order.BOOKINGNO = flowno;
await _rep.AsUpdateable(order).UpdateColumns(x => new { x.BOOKINGNO }).ExecuteCommandAsync(); await _rep.AsUpdateable(order).UpdateColumns(x => new { x.BOOKINGNO }).ExecuteCommandAsync();
_logger.LogInformation("批次={no} INTTRA 判断业务编号长度不能大于14重新生成 MBLNO={mblno} custno={custno} 新单号{flowno}", batchNo, primaryModel.MBLNO, order.BOOKINGNO, flowno); _logger.LogInformation("批次={no} INTTRA 判断业务编号长度不能大于14重新生成 MBLNO={mblno} BOOKINGNO={BOOKINGNO} 新单号{flowno}", batchNo, primaryModel.MBLNO, order.BOOKINGNO, flowno);
} }
} }
} }

@ -45,6 +45,22 @@ namespace Myshipping.Application.Service.TaskManagePlat.Dtos
/// 生成时间 /// 生成时间
/// </summary> /// </summary>
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
/// <summary>
/// 原因
/// </summary>
public string Reason { get; set; }
/// <summary>
/// 装货港区域 NORTH_PORT-华北港口 SOUTH-华南港口
/// </summary>
public string PortLoadArea { get; set; }
/// <summary>
/// 提单号
/// </summary>
public string MBLNo { get; set; }
} }
/// <summary> /// <summary>
@ -136,5 +152,41 @@ namespace Myshipping.Application.Service.TaskManagePlat.Dtos
/// 截关时间文本 海关放行截止时间(Customs Clearance Deadline) /// 截关时间文本 海关放行截止时间(Customs Clearance Deadline)
/// </summary> /// </summary>
public string ClosingDateTxt { get; set; } public string ClosingDateTxt { get; set; }
/// <summary>
/// 提单补料截止时间
/// </summary>
public Nullable<DateTime> VoucherCutoffTime { get; set; }
/// <summary>
/// 提单补料截止时间文本
/// </summary>
public string VoucherCutoffTimeTxt { get; set; }
/// <summary>
/// 装货港
/// </summary>
public string LoadPort { get; set; }
/// <summary>
/// 预计到港
/// </summary>
public Nullable<DateTime> ETD { get; set; }
/// <summary>
/// 预计靠泊
/// </summary>
public Nullable<DateTime> ETB { get; set; }
/// <summary>
/// 集装箱号
/// </summary>
public string ContaNo { get; set; }
/// <summary>
/// 原因
/// </summary>
public string Reason { get; set; }
} }
} }

@ -105,5 +105,35 @@ namespace Myshipping.Application
/// 通知接收时间 /// 通知接收时间
/// </summary> /// </summary>
public Nullable<DateTime> NoticeDate { get; set; } public Nullable<DateTime> NoticeDate { get; set; }
/// <summary>
/// 原因
/// </summary>
public string Reason { get; set; }
/// <summary>
/// 集装箱号
/// </summary>
public string ContaNo { get; set; }
/// <summary>
/// 装货港
/// </summary>
public string LoadPort { get; set; }
/// <summary>
/// 预计离港时间
/// </summary>
public Nullable<DateTime> ETD { get; set; }
/// <summary>
/// 预计靠泊时间
/// </summary>
public Nullable<DateTime> ETB { get; set; }
/// <summary>
/// 截补料时间
/// </summary>
public Nullable<DateTime> VoucherCutoffTime { get; set; }
} }
} }

@ -988,7 +988,10 @@ namespace Myshipping.Application
.Map(dest => dest.VESSEL, src => src.Vessel) .Map(dest => dest.VESSEL, src => src.Vessel)
.Map(dest => dest.VOYNO, src => src.VoyNo) .Map(dest => dest.VOYNO, src => src.VoyNo)
.Map(dest => dest.NOTICE_DATE, src => src.CreateTime) .Map(dest => dest.NOTICE_DATE, src => src.CreateTime)
.Map(dest => dest.VESSEL, src => src.Vessel); .Map(dest => dest.VESSEL, src => src.Vessel)
.Map(dest => dest.MBL_NO, src => src.MBLNo)
.Map(dest => dest.PORTLOAD_AREA, src => src.PortLoadArea)
.Map(dest => dest.REASON, src => src.Reason);
config.ForType<CutDateChangeDetailDto, TaskCutDateChangeDetailInfo>() config.ForType<CutDateChangeDetailDto, TaskCutDateChangeDetailInfo>()
@ -1008,8 +1011,13 @@ namespace Myshipping.Application
.Map(dest => dest.VGM_CUT, src => src.VGMCutoffTime) .Map(dest => dest.VGM_CUT, src => src.VGMCutoffTime)
.Map(dest => dest.VGM_CUT_TXT, src => src.VGMCutoffTimeTxt) .Map(dest => dest.VGM_CUT_TXT, src => src.VGMCutoffTimeTxt)
.Map(dest => dest.CLOSING_DATE, src => src.ClosingDate) .Map(dest => dest.CLOSING_DATE, src => src.ClosingDate)
.Map(dest => dest.CLOSING_DATE_TXT, src => src.ClosingDateTxt); .Map(dest => dest.CLOSING_DATE_TXT, src => src.ClosingDateTxt)
.Map(dest => dest.VOUCHER_CUT_DATE, src => src.VoucherCutoffTime)
.Map(dest => dest.LOAD_PORT, src => src.LoadPort)
.Map(dest => dest.ETD, src => src.ETD)
.Map(dest => dest.ETB, src => src.ETB)
.Map(dest => dest.REASON, src => src.Reason)
.Map(dest => dest.CONTA_NO, src => src.ContaNo);
config.ForType<TaskCutDateChangeDetailInfo, TaskCutDateChangeShowDto>() config.ForType<TaskCutDateChangeDetailInfo, TaskCutDateChangeShowDto>()
.Map(dest => dest.MBLNo, src => src.MBL_NO) .Map(dest => dest.MBLNo, src => src.MBL_NO)
@ -1028,8 +1036,12 @@ namespace Myshipping.Application
.Map(dest => dest.VGMCutoffTime, src => src.VGM_CUT) .Map(dest => dest.VGMCutoffTime, src => src.VGM_CUT)
.Map(dest => dest.VGMCutoffTimeTxt, src => src.VGM_CUT_TXT) .Map(dest => dest.VGMCutoffTimeTxt, src => src.VGM_CUT_TXT)
.Map(dest => dest.ClosingDate, src => src.CLOSING_DATE) .Map(dest => dest.ClosingDate, src => src.CLOSING_DATE)
.Map(dest => dest.ClosingDateTxt, src => src.CLOSING_DATE_TXT); .Map(dest => dest.ClosingDateTxt, src => src.CLOSING_DATE_TXT)
.Map(dest => dest.ContaNo, src => src.CONTA_NO)
.Map(dest => dest.LoadPort, src => src.LOAD_PORT)
.Map(dest => dest.ETB, src => src.ETB)
.Map(dest => dest.ETD, src => src.ETD)
.Map(dest => dest.VoucherCutoffTime, src => src.VOUCHER_CUT_DATE);
config.ForType<TaskManageOrderSIFeedBackInfo, TaskSISubmitted>() config.ForType<TaskManageOrderSIFeedBackInfo, TaskSISubmitted>()
.Map(dest => dest.MBL_NO, src => src.MblNo) .Map(dest => dest.MBL_NO, src => src.MblNo)

@ -36,5 +36,26 @@ namespace Myshipping.Application
/// <param name="taskPkId">截止时间变更任务主键</param> /// <param name="taskPkId">截止时间变更任务主键</param>
/// <returns>返回回执</returns> /// <returns>返回回执</returns>
Task<TaskManageOrderResultDto> SendInstantMessage(string taskPkId); Task<TaskManageOrderResultDto> SendInstantMessage(string taskPkId);
/// <summary>
/// 自动转发截止时间变更
/// </summary>
/// <param name="taskPKId">截止时间变更任务主键</param>
/// <returns>返回回执</returns>
Task<TaskManageOrderResultDto> AutoTransferNotice(string taskPKId);
/// <summary>
/// 检索对应的订舱订单
/// </summary>
/// <param name="taskPKId">截止时间变更任务主键</param>
/// <returns>返回回执</returns>
Task<TaskManageOrderResultDto> QueryBookingOrder(string taskPKId);
/// <summary>
/// 发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">截止时间变更主键</param>
/// <returns>返回回执</returns>
Task<TaskManageOrderResultDto> SendEmailToCustomer(string taskPKId);
} }
} }

@ -1,17 +1,30 @@
using Furion.DynamicApiController; using Furion;
using Furion.DynamicApiController;
using Furion.FriendlyException; using Furion.FriendlyException;
using Furion.JsonSerialization;
using Furion.RemoteRequest.Extensions;
using HtmlAgilityPack;
using Mapster; using Mapster;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Myshipping.Application.ConfigOption;
using Myshipping.Application.Entity; using Myshipping.Application.Entity;
using Myshipping.Application.Enum;
using Myshipping.Application.Helper;
using Myshipping.Core; using Myshipping.Core;
using Myshipping.Core.Entity;
using Myshipping.Core.Helper; using Myshipping.Core.Helper;
using Myshipping.Core.Service;
using Newtonsoft.Json;
using Npoi.Mapper; using Npoi.Mapper;
using NPOI.OpenXmlFormats.Wordprocessing; using NPOI.OpenXmlFormats.Wordprocessing;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using SqlSugar; using SqlSugar;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -27,16 +40,35 @@ namespace Myshipping.Application
private readonly SqlSugarRepository<TaskCutDateChangeDetailInfo> _taskCutDateChangeDetailInfoRepository; private readonly SqlSugarRepository<TaskCutDateChangeDetailInfo> _taskCutDateChangeDetailInfoRepository;
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository; private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository; private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
private readonly ILogger<TaskManageCutDateChangeService> _logger;
private readonly SqlSugarRepository<BookingOrderContact> _bookingOrderContactRepository;
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccount;
private readonly SqlSugarRepository<BookingPrintTemplate> _repPrintTemplate;
private readonly ISysCacheService _cache;
public TaskManageCutDateChangeService(SqlSugarRepository<TaskCutDateChangeInfo> taskCutDateChangeInfoRepository, public TaskManageCutDateChangeService(SqlSugarRepository<TaskCutDateChangeInfo> taskCutDateChangeInfoRepository,
SqlSugarRepository<TaskCutDateChangeDetailInfo> taskCutDateChangeDetailInfoRepository, SqlSugarRepository<TaskCutDateChangeDetailInfo> taskCutDateChangeDetailInfoRepository,
SqlSugarRepository<BookingOrderContact> bookingOrderContactRepository,
SqlSugarRepository<TaskBaseInfo> taskBaseRepository, SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
SqlSugarRepository<SysUser> sysUserRepository,
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount,
SqlSugarRepository<BookingPrintTemplate> repPrintTemplate,
ILogger<TaskManageCutDateChangeService> logger,
ISysCacheService cache,
SqlSugarRepository<BookingOrder> bookingOrderRepository) SqlSugarRepository<BookingOrder> bookingOrderRepository)
{ {
_taskCutDateChangeInfoRepository = taskCutDateChangeInfoRepository; _taskCutDateChangeInfoRepository = taskCutDateChangeInfoRepository;
_taskCutDateChangeDetailInfoRepository = taskCutDateChangeDetailInfoRepository; _taskCutDateChangeDetailInfoRepository = taskCutDateChangeDetailInfoRepository;
_taskBaseRepository = taskBaseRepository; _taskBaseRepository = taskBaseRepository;
_bookingOrderRepository = bookingOrderRepository; _bookingOrderRepository = bookingOrderRepository;
_bookingOrderContactRepository = bookingOrderContactRepository;
_sysUserRepository = sysUserRepository;
_djyUserMailAccount = djyUserMailAccount;
_repPrintTemplate = repPrintTemplate;
_logger = logger;
_cache = cache;
} }
#region 获取截止时间变更详情 #region 获取截止时间变更详情
@ -259,5 +291,608 @@ namespace Myshipping.Application
return result; return result;
} }
#endregion #endregion
#region 自动转发截止时间变更通知
/// <summary>
/// 自动转发截止时间变更通知
/// </summary>
/// <param name="taskPKId">截止时间变更通知任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageCutDate/AutoTransferNotice")]
public async Task<TaskManageOrderResultDto> AutoTransferNotice(string taskPKId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var queryRlt = QueryBookingOrder(taskPKId);
_logger.LogInformation($"taskPKId={taskPKId} 检索对应的订舱记录完成,结果:{JSON.Serialize(queryRlt)}");
//_logger.LogInformation($"taskPKId={taskPKId} 当前租户未开启货物运输计划已变更是否同批次同客户合并邮件通知,按照单票推送邮件处理");
//如果没有配置批量,则按单票发送邮件
var rlt = SendEmailToCustomer(taskPKId);
_logger.LogInformation($"taskPKId={taskPKId} 推送邮件完成,结果:{JSON.Serialize(rlt)}");
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"自动转发截止时间变更失败,原因:{ex.Message}";
_logger.LogInformation($"taskPKId={taskPKId} 自动转发截止时间变更失败,原因:{ex.Message}");
}
return result;
}
#endregion
#region 检索对应的订舱订单
/// <summary>
/// 检索对应的订舱订单
/// </summary>
/// <param name="taskPKId">截止时间变更任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageCutDate/QueryBookingOrder")]
public async Task<TaskManageOrderResultDto> QueryBookingOrder(string taskPKId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var taskBase = _taskBaseRepository.AsQueryable().Filter(null, true).First(a => a.PK_ID == taskPKId);
if (taskBase == null)
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
var entityInfo = _taskCutDateChangeInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == taskBase.PK_ID);
if (entityInfo == null)
throw Oops.Oh($"起运港未提箱主键{taskPKId}无法获取业务信息");
//通过船名航次取是主单的订舱记录列表
var bookingInfo = _bookingOrderRepository.AsQueryable().Filter(null, true).First(a => a.MBLNO == entityInfo.MBL_NO
&& a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0) && a.TenantId == UserManager.TENANT_ID);
if (bookingInfo != null)
{
entityInfo.BOOKING_ID = bookingInfo.Id;
entityInfo.UpdatedTime = DateTime.Now;
entityInfo.UpdatedUserId = UserManager.UserId;
entityInfo.UpdatedUserName = UserManager.Name;
await _taskCutDateChangeInfoRepository.AsUpdateable(entityInfo).UpdateColumns(x => new {
x.BOOKING_ID,
x.UpdatedTime,
x.UpdatedUserId,
x.UpdatedUserName
}).ExecuteCommandAsync();
var list = _taskCutDateChangeDetailInfoRepository.AsQueryable().Filter(null, true).Where(a => a.P_ID == entityInfo.PK_ID).ToList();
if(list != null && list.Count > 0)
{
list.ForEach(async p =>
{
if (p.MBL_NO.Equals(entityInfo.MBL_NO, StringComparison.OrdinalIgnoreCase))
{
p.BOOKING_ID = bookingInfo.Id;
p.UpdatedTime = DateTime.Now;
p.UpdatedUserId = UserManager.UserId;
p.UpdatedUserName = UserManager.Name;
await _taskCutDateChangeDetailInfoRepository.AsUpdateable(p).UpdateColumns(x => new {
x.BOOKING_ID,
x.UpdatedTime,
x.UpdatedUserId,
x.UpdatedUserName
}).ExecuteCommandAsync();
}
});
}
result.succ = true;
result.msg = "检索对应成功";
}
else
{
result.succ = false;
result.msg = $"检索对应失败,提单号:{entityInfo.MBL_NO} 没有对应的订舱记录";
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"检索失败,原因:{ex.Message}";
_logger.LogInformation($"taskPKId={taskPKId} 检索起运港未提箱订舱记录 处理异常,原因:{ex.Message}");
}
return result;
}
#endregion
#region 发送邮件通知给客户
/// <summary>
/// 发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">起运港未提箱通知主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageCutDate/SendEmailToCustomer")]
public async Task<TaskManageOrderResultDto> SendEmailToCustomer(string taskPKId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var entityInfo = _taskCutDateChangeInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == taskPKId);
var list = _taskCutDateChangeDetailInfoRepository.AsQueryable().Filter(null, true).Where(a => a.P_ID == entityInfo.PK_ID).ToList();
if (!entityInfo.BOOKING_ID.HasValue)
{
new EmailNoticeHelper().SendEmailNotice($"taskid={taskPKId} mblno={entityInfo.MBL_NO} 起运港未提箱 转发通知邮件失败", $"taskid={taskPKId} mblno={entityInfo.MBL_NO} 当前任务没有对应的订舱订单,不能转发邮件,请先检索对应的订舱订单", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
throw Oops.Oh($"当前任务没有对应的订舱订单,不能转发邮件,请先检索对应的订舱订单");
}
var bookingOrderList = _bookingOrderRepository.AsQueryable().Filter(null, true).Where(a => a.Id == entityInfo.BOOKING_ID.Value && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID).ToList();
if (bookingOrderList.Count == 0)
{
new EmailNoticeHelper().SendEmailNotice($"taskid={taskPKId} mblno={entityInfo.MBL_NO} 起运港未提箱 转发通知邮件失败", $"taskid={taskPKId} mblno={entityInfo.MBL_NO} 当前任务对应的订舱订单不存在或已作废", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
throw Oops.Oh($"当前任务对应的订舱订单不存在或已作废");
}
var bookingId = entityInfo.BOOKING_ID.Value;
var bookingContactList = _bookingOrderContactRepository.AsQueryable().Filter(null, true)
.Where(a => bookingId == a.BookingId.Value && a.IsDeleted == false).ToList();
result = await GenerateSendEmail(entityInfo, list, bookingOrderList, bookingContactList);
list.ForEach(async p =>
{
var model = _taskCutDateChangeDetailInfoRepository.AsQueryable().Filter(null, true).First(a => a.PK_ID == p.PK_ID);
if (model != null)
{
model.IS_NOTICE = true;
model.STATUS = result.succ ? "SUCC" : "FAILURE";
model.STATUS_NAME = result.succ ? "成功" : "失败";
model.NOTICE_DATE = DateTime.Now;
await _taskCutDateChangeDetailInfoRepository.AsUpdateable(model).UpdateColumns(x => new
{
x.IS_NOTICE,
x.STATUS,
x.STATUS_NAME,
x.NOTICE_DATE,
}).ExecuteCommandAsync();
}
});
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"发送邮件失败,原因:{ex.Message}";
}
return result;
}
#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<BookingOrder> bookingOrderList, List<BookingOrderContact> 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>();
SysUser opUserInfo = null;
bookingOrderList.ForEach(bk =>
{
//获取操作OP的邮箱
if (!string.IsNullOrWhiteSpace(bk.OPID))
{
var opId = long.Parse(bk.OPID);
var opUser = _sysUserRepository.AsQueryable().Filter(null, true).First(a => a.Id == opId);
if (opUser != null)
{
if (opUserInfo == null)
opUserInfo = opUser;
if (!string.IsNullOrWhiteSpace(opUser.Email))
{
opEmailList.Add(opUser.Email.Trim());
_logger.LogInformation($"id={bk.Id} mblno={bk.MBLNO} 获取操作OP的邮箱opEmail={opEmail} opid={opId} name={opUser.Name}");
}
else
{
_logger.LogInformation($"id={bk.Id} mblno={bk.MBLNO} 获取操作OP的邮箱失败opEmail={opUser.Email} opid={opId} name={opUser.Name}");
}
}
else
{
_logger.LogInformation($"id={bk.Id} mblno={bk.MBLNO} 检索操作OP信息失败opid={opId} name={opUser.Name}");
}
}
//获取客服的邮箱
if (!string.IsNullOrWhiteSpace(bk.CUSTSERVICEID))
{
var opId = long.Parse(bk.CUSTSERVICEID);
var opUser = _sysUserRepository.AsQueryable().Filter(null, true).First(a => a.Id == opId);
if (opUser != null)
{
if (!string.IsNullOrWhiteSpace(opUser.Email))
{
opEmailList.Add(opUser.Email.Trim());
_logger.LogInformation($"id={bk.Id} mblno={bk.MBLNO} 获取客服的邮箱opEmail={opEmail} opid={opId} name={opUser.Name}");
}
else
{
_logger.LogInformation($"id={bk.Id} mblno={bk.MBLNO} 获取客服的邮箱失败opEmail={opUser.Email} opid={opId} name={opUser.Name}");
}
}
else
{
_logger.LogInformation($"id={bk.Id} mblno={bk.MBLNO} 检索客服信息失败opid={opId} name={opUser.Name}");
}
}
});
if (opEmailList.Count > 0)
opEmail = string.Join(";", opEmailList.Distinct().ToArray());
string 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.LogInformation($"提取当前公共邮箱的配置完成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"));
if (printTemplate == null)
{
throw Oops.Bah(BookingErrorCode.BOOK115);
}
//读取邮件模板并填充数据
string emailHtml = GenerateSendEmailHtml(model, rowList, bookingOrderList, printTemplate.FilePath, opUserInfo, UserManager.TENANT_NAME).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>()
};
_logger.LogInformation($"生成请求邮件参数,结果:{JSON.Serialize(emailApiUserDefinedDto)}");
//推送邮件
var emailRlt = await PushEmail(emailApiUserDefinedDto);
_logger.LogInformation($"推送邮件完成,结果:{JSON.Serialize(emailRlt)}");
if (emailRlt.succ)
{
result.succ = true;
result.msg = "成功";
}
else
{
result.succ = false;
result.msg = emailRlt.msg;
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="bookingOrderList"></param>
/// <param name="filePath"></param>
/// <param name="opUserInfo"></param>
/// <param name="tenantName"></param>
/// <returns></returns>
[NonAction]
private async Task<string> GenerateSendEmailHtml(TaskCutDateChangeInfo model,List<TaskCutDateChangeDetailInfo> rowList, List<BookingOrder> bookingOrderList,
string filePath, SysUser opUserInfo, string tenantName)
{
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.Name))
{
baseHtml = baseHtml.Replace("#opname#", opUserInfo.Name);
}
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 (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()));
}
result = html.DocumentNode.OuterHtml;
}
catch (Exception ex)
{
_logger.LogInformation($"生成截止时间变更正文失败,原因:{ex.Message}");
throw Oops.Bah($"生成截止时间变更正文失败,原因:{ex.Message}");
}
return result;
}
#endregion
#region 推送邮件
/// <summary>
/// 推送邮件
/// </summary>
/// <param name="emailApiUserDefinedDto">自定义邮件详情</param>
/// <param name="filePath">文件路径</param>
/// <returns>返回回执</returns>
[NonAction]
private async Task<CommonWebApiResult> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto)
{
CommonWebApiResult result = new CommonWebApiResult { succ = true };
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
var emailUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "email_api_url")?.Value;
if (emailUrl == null)
throw Oops.Bah("字典未配置 url_set->email_api_url 请联系管理员");
emailList.Add(emailApiUserDefinedDto);
//string strJoin = System.IO.File.ReadAllText(filePath);
DateTime bDate = DateTime.Now;
HttpResponseMessage res = null;
try
{
res = await emailUrl.SetBody(emailList, "application/json").PostAsync();
}
catch (Exception ex)
{
_logger.LogInformation($"发送邮件异常:{ex.Message}");
}
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation($"发送邮件返回:{JSON.Serialize(res)}");
if (res != null && res.StatusCode == System.Net.HttpStatusCode.OK)
{
var userResult = await res.Content.ReadAsStringAsync();
var respObj = JsonConvert.DeserializeAnonymousType(userResult, new
{
Success = false,
Message = string.Empty,
Code = -9999,
});
result.succ = respObj.Success;
result.msg = respObj.Message;
}
return result;
}
#endregion
} }
} }

@ -1066,7 +1066,7 @@ namespace Myshipping.Application
if (info.Main.CutDateChange.Details != null && info.Main.CutDateChange.Details.Count > 0) if (info.Main.CutDateChange.Details != null && info.Main.CutDateChange.Details.Count > 0)
{ {
//异步写入集装箱 //异步写入明细
info.Main.CutDateChange.Details.ForEach(detail => info.Main.CutDateChange.Details.ForEach(detail =>
{ {
var cutDetail = detail.Adapt<TaskCutDateChangeDetailInfo>(); var cutDetail = detail.Adapt<TaskCutDateChangeDetailInfo>();

Loading…
Cancel
Save