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.
BookingHeChuan/Myshipping.Application/Service/TaskManagePlat/RouteChangeAdvisoryService.cs

831 lines
36 KiB
C#

This file contains ambiguous Unicode 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 Furion.DependencyInjection;
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Myshipping.Application.Entity;
using Myshipping.Core.Entity;
using Myshipping.Core.Service;
using Myshipping.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Furion.FriendlyException;
using NPOI.POIFS.Storage;
using Yitter.IdGenerator;
using Furion.DistributedIDGenerator;
using System.Text.RegularExpressions;
using Furion;
using Myshipping.Application.Helper;
using HtmlAgilityPack;
using Myshipping.Application.ConfigOption;
using Myshipping.Application.Enum;
using System.IO;
using StackExchange.Profiling.Internal;
using Furion.JsonSerialization;
using MySqlX.XDevAPI.Common;
using Furion.RemoteRequest.Extensions;
using Newtonsoft.Json;
using System.Net.Http;
using SqlSugar;
namespace Myshipping.Application
{
/// <summary>
/// 船舶相关截止时间的通知
/// </summary>
[ApiDescriptionSettings("Application", Name = "RouteChangeAdvisory", Order = 10)]
public class RouteChangeAdvisoryService : IRouteChangeAdvisoryService, IDynamicApiController, ITransient
{
private readonly ISysCacheService _cache;
private readonly ILogger<TaskCautionNoticeService> _logger;
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
private readonly SqlSugarRepository<TaskRouteChangeAdvisoryInfo> _taskRouteChangeAdvisoryInfoRepository;
private readonly SqlSugarRepository<TaskRouteChangeAdvisoryDetailInfo> _taskRouteChangeAdvisoryDetailInfoRepository;
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccount;
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
private readonly SqlSugarRepository<BookingOrderContact> _bookingOrderContactRepository;
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
private readonly SqlSugarRepository<BookingPrintTemplate> _repPrintTemplate;
private readonly SqlSugarRepository<TaskFileInfo> _taskFileRepository;
private readonly IDjyTenantParamService _djyTenantParamService;
public RouteChangeAdvisoryService(ISysCacheService cache, ILogger<TaskCautionNoticeService> logger,
SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
SqlSugarRepository<TaskRouteChangeAdvisoryInfo> taskRouteChangeAdvisoryInfoRepository,
SqlSugarRepository<TaskRouteChangeAdvisoryDetailInfo> taskRouteChangeAdvisoryDetailInfoRepository,
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount,
SqlSugarRepository<BookingOrderContact> bookingOrderContactRepository,
SqlSugarRepository<SysUser> sysUserRepository,
SqlSugarRepository<BookingPrintTemplate> repPrintTemplate,
SqlSugarRepository<TaskFileInfo> taskFileRepository,
SqlSugarRepository<BookingOrder> bookingOrderRepository, IDjyTenantParamService djyTenantParamService)
{
_cache = cache;
_logger = logger;
_taskBaseRepository = taskBaseRepository;
_taskRouteChangeAdvisoryInfoRepository = taskRouteChangeAdvisoryInfoRepository;
_taskRouteChangeAdvisoryDetailInfoRepository = taskRouteChangeAdvisoryDetailInfoRepository;
_djyUserMailAccount = djyUserMailAccount;
_bookingOrderRepository = bookingOrderRepository;
_bookingOrderContactRepository = bookingOrderContactRepository;
_sysUserRepository = sysUserRepository;
_repPrintTemplate = repPrintTemplate;
_taskFileRepository = taskFileRepository;
_djyTenantParamService = djyTenantParamService;
}
#region 获取船舶相关截止时间的通知详情
/// <summary>
/// 获取船舶相关截止时间的通知详情
/// </summary>
/// <param name="taskPkId">船舶相关截止时间的通知任务主键</param>
/// <returns>返回详情</returns>
[HttpGet("/RouteChangeAdvisory/GetInfoByTaskId")]
public async Task<TaskRouteChangeAdvisoryShowDto> GetInfoByTaskId(string taskPkId)
{
TaskRouteChangeAdvisoryShowDto dto = new TaskRouteChangeAdvisoryShowDto();
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId);
if (taskBase == null)
throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息");
var advisoryInfo = _taskRouteChangeAdvisoryInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID);
if (advisoryInfo == null)
throw Oops.Oh($"船舶相关截止时间的通知主键{taskPkId}无法获取业务信息");
var detailList = _taskRouteChangeAdvisoryDetailInfoRepository.AsQueryable()
.Where(a => a.P_ID == advisoryInfo.PK_ID).ToList();
dto = new TaskRouteChangeAdvisoryShowDto
{
PKId = advisoryInfo.PK_ID,
TaskPKId = advisoryInfo.TASK_ID,
CarrierId = advisoryInfo.CARRIER,
CreateTime = advisoryInfo.CreatedTime,
AdvisoryTitle = advisoryInfo.EMAIL_SUBJECT,
CYCutDate = advisoryInfo.CY_CUT_DATE,
ETA = advisoryInfo.ETA,
ETD = advisoryInfo.ETD,
MDGFCutDate = advisoryInfo.MDGF_CUT_DATE,
origETD = advisoryInfo.ORIG_ETD,
RouteCode = advisoryInfo.ROUTE_CODE,
SICutDate = advisoryInfo.SI_CUT_DATE,
Vessel = advisoryInfo.VESSEL,
Voyno = advisoryInfo.VOYNO,
VGMCutDate = advisoryInfo.VGM_CUTOFF_TIME,
Week = advisoryInfo.WEEK,
TerminalShiftCutDate = advisoryInfo.TM_SHIFT_CUT_DATE,
LoadPort = advisoryInfo.READ_PORTLOAD,
LoadPortId = advisoryInfo.PORTLOADID,
LoadPortName = advisoryInfo.PORTLOAD,
BuisList = new List<TaskRouteChangeAdvisoryBusiShowDto>()
};
if (detailList.Count > 0)
{
var queryList = detailList.Where(a => a.BOOKING_ID.HasValue).Select(a => a.BOOKING_ID.Value).ToList();
if (queryList.Count > 0)
{
//查询整船的订舱订单列表
var bookList = _bookingOrderRepository.AsQueryable().Where(a => queryList.Contains(a.Id) && a.IsDeleted == false).ToList();
dto.BuisList = detailList.Select(p => {
TaskRouteChangeAdvisoryBusiShowDto detail = new TaskRouteChangeAdvisoryBusiShowDto {
PKId = p.PK_ID,
LstTransferUserDate = p.LST_TRANSFER_USER_DATE,
IsTransferUser = p.IS_TRANSFER_USER,
LstTransferNote = p.LST_TRANSFER_NOTES,
BookingId = p.BOOKING_ID.Value,
IsEnable = p.IS_ENABLE,
LstStatus = p.LST_STATUS,
LstStatusName = p.LST_STATUS_NAME,
};
var bookInfo = bookList.FirstOrDefault(x => x.Id == p.BOOKING_ID.Value);
if (bookInfo != null)
{
detail.CustomerName = bookInfo.CUSTOMERNAME;
detail.MBlNo = bookInfo.MBLNO;
}
else
{
//如果对应的订舱已被作废,只能标记不可发送
detail.IsEnable = false;
}
return detail;
}).ToList();
}
else
{
dto.BuisList = detailList.Select(p => {
TaskRouteChangeAdvisoryBusiShowDto detail = new TaskRouteChangeAdvisoryBusiShowDto
{
PKId = p.PK_ID,
LstTransferUserDate = p.LST_TRANSFER_USER_DATE,
IsTransferUser = p.IS_TRANSFER_USER,
LstTransferNote = p.LST_TRANSFER_NOTES,
BookingId = p.BOOKING_ID.Value,
IsEnable = false,
LstStatus = p.LST_STATUS,
LstStatusName = p.LST_STATUS_NAME,
};
return detail;
}).ToList();
}
}
return dto;
}
#endregion
#region 自动转发船舶相关截止时间的通知
/// <summary>
/// 自动转发船舶相关截止时间的通知
/// </summary>
/// <param name="taskPKId">船舶相关截止时间的通知任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/RouteChangeAdvisory/AutoTransferNotice")]
public async Task<TaskManageOrderResultDto> AutoTransferNotice(string taskPKId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var queryRlt = await QueryVesselVoynoBookingOrder(taskPKId);
_logger.LogInformation($"taskPKId={taskPKId} 检索对应的订舱记录完成,结果:{JSON.Serialize(queryRlt)}");
var model = _taskRouteChangeAdvisoryInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == taskPKId);
var list =_taskRouteChangeAdvisoryDetailInfoRepository.AsQueryable().Filter(null,true).Where(a=>a.P_ID == model.PK_ID
&& a.IsDeleted == false).ToList();
var pkList = list.Select(a => a.PK_ID).ToList();
//如果没有配置批量,则按单票发送邮件
var rlt = BatchSendEmailToCustomer(pkList.ToArray());
_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("/RouteChangeAdvisory/QueryVesselVoynoBookingOrder")]
public async Task<TaskManageOrderResultDto> QueryVesselVoynoBookingOrder(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 advisoryInfo = _taskRouteChangeAdvisoryInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == taskBase.PK_ID);
if (advisoryInfo == null)
throw Oops.Oh($"船舶相关截止时间的通知主键{taskPKId}无法获取业务信息");
var detailList = _taskRouteChangeAdvisoryDetailInfoRepository.AsQueryable().Filter(null, true)
.Where(a => a.P_ID == advisoryInfo.PK_ID).ToList();
//通过船名、航次、装货港、取是主单的订舱记录列表
var bookList = _bookingOrderRepository.AsQueryable().Filter(null, true).Where(a => a.VESSEL == advisoryInfo.VESSEL
&& (a.VOYNO == advisoryInfo.VOYNO || a.VOYNOINNER == advisoryInfo.VOYNO) && a.PORTLOADID == advisoryInfo.PORTLOADID
&& a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0)).ToList();
//用查询到的订舱列表和明细记录标做匹配,如果没有需要新增记录表
var addList = bookList.GroupJoin(detailList, l => l.Id, r => r.BOOKING_ID.Value, (l, r) =>
{
var currList = r.ToList();
if (currList.Count == 0)
{
return new { IsAdd = true, book = l };
}
return new { IsAdd = false, book = l };
}).Where(t => t.IsAdd).Select(t => t.book).ToList();
DateTime nowDate = DateTime.Now;
if (addList.Count > 0)
{
addList.ForEach(t =>
{
TaskRouteChangeAdvisoryDetailInfo detail = new TaskRouteChangeAdvisoryDetailInfo
{
PK_ID = IDGen.NextID().ToString(),
P_ID = advisoryInfo.PK_ID,
IsDeleted = false,
BOOKING_ID = t.Id,
MBL_NO = t.MBLNO,
CreatedTime = nowDate,
UpdatedTime = nowDate,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name,
TenantId = UserManager.TENANT_ID,
IS_ENABLE = true,
};
_taskRouteChangeAdvisoryDetailInfoRepository.Insert(detail);
});
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"检索失败,原因:{ex.Message}";
_logger.LogInformation($"taskPKId={taskPKId} 检索同一航次对应的订舱订单(并对应记录) 处理异常,原因:{ex.Message}");
new EmailNoticeHelper().SendEmailNotice($"taskid={taskPKId} Advisory 换船提醒 转发通知邮件失败", $"taskid={taskPKId} 换船提醒 转发通知邮件失败,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
}
return result;
}
#endregion
#region 批量发送邮件通知给客户
/// <summary>
/// 批量发送邮件通知给客户
/// </summary>
/// <param name="detailPKIds">船舶相关截止时间的通知订舱明细记录主键组</param>
/// <returns>返回回执</returns>
[HttpPost("/RouteChangeAdvisory/BatchSendEmailToCustomer")]
public async Task<TaskManageOrderResultDto> BatchSendEmailToCustomer([FromBody] string[] detailPKIds)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
if (detailPKIds == null || detailPKIds.Length == 0)
throw Oops.Oh($"未选择需要发送订单明细");
var detailList = _taskRouteChangeAdvisoryDetailInfoRepository.AsQueryable().Filter(null, true)
.Where(a => detailPKIds.Contains(a.PK_ID) && a.IsDeleted == false).ToList();
if (detailPKIds.Length != detailList.Count)
{
throw Oops.Oh($"检索明细数据失败,检索数据不存在或已作废");
}
var pId = detailList.FirstOrDefault().P_ID;
var advisoryModel = _taskRouteChangeAdvisoryInfoRepository.AsQueryable().Filter(null, true).First(a => a.PK_ID == pId);
TaskBaseInfo taskBaskInfo = new TaskBaseInfo();
if (advisoryModel != null)
{
taskBaskInfo = _taskBaseRepository.AsQueryable().Filter(null, true).First(a => a.PK_ID == advisoryModel.TASK_ID);
}
var bookIdList = detailList.Where(t => t.IS_ENABLE == true)
.Select(t => t.BOOKING_ID.Value).ToList();
if (detailList.Any(a => !a.BOOKING_ID.HasValue))
{
throw Oops.Oh($"明细相关的订舱数据检索失败,请确认订舱数据是否存在");
}
//需要根据订单的往来单位统一推送一封邮件,里面有提单号列表
var bookList = _bookingOrderRepository.AsQueryable().Filter(null, true).Where(a => bookIdList.Contains(a.Id)
&& a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0)).ToList();
var checkList = detailList.GroupJoin(bookList, l => l.BOOKING_ID.Value, r => r.Id, (l, r) =>
{
var currList = r.ToList();
if (currList.Count == 0)
return new { IsNoBooking = true, MblNo = l.MBL_NO };
return new { IsNoBooking = false, MblNo = l.MBL_NO };
}).Where(a => a.IsNoBooking).Select(a => a.MblNo).ToList();
if (checkList.Count > 0)
{
throw Oops.Oh($"明细提单号对应订舱没有记录,{string.Join(",", checkList.ToArray())}");
}
var bookingContactList = _bookingOrderContactRepository.AsQueryable().Filter(null, true)
.Where(a => bookIdList.Contains(a.BookingId.Value) && a.IsDeleted == false).ToList();
//还需要判断订舱是否录了客户联系人
var checkContactList = bookList.GroupJoin(bookingContactList, l => l.Id, r => r.BookingId.Value, (l, r) =>
{
var currList = r.ToList();
if (currList.Count == 0)
return new { IsNoContact = true,IsNoEmail = false, book = l };
if (currList.Count(p => string.IsNullOrWhiteSpace(p.Email)) > 0)
return new { IsNoContact = true, IsNoEmail = true, book = l };
return new { IsNoContact = false, IsNoEmail = false, book = l };
}).Where(a=>a.IsNoContact).ToList();
if (checkContactList.Count > 0)
{
var currList = checkContactList.Select(a => a.book.MBLNO).ToList();
throw Oops.Oh($"以下订舱订单未指定往来单位联系人或联系人未填写邮箱,请修改订舱信息,{string.Join(",", checkList.ToArray())}");
}
//按照往来单位来合并订单,一个客户一个邮件来提醒
var gList = bookList.GroupBy(a => a.CUSTOMERID).Select(a =>
{
var currList = a.ToList();
return new { CustId = a.Key, CustName = currList.FirstOrDefault().CUSTOMERNAME, OrderList = currList };
}).ToList();
gList.ForEach(book =>
{
var currBookIdList = book.OrderList.Select(x => x.Id).ToList();
var currContactList = bookingContactList.Where(p => currBookIdList.Contains(p.BookingId.Value)).ToList();
var rlt = GenerateSendEmail(advisoryModel,book.OrderList, currContactList, taskBaskInfo).GetAwaiter().GetResult();
});
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"批量发送失败,原因:{ex.Message}";
_logger.LogInformation($"detailPKIds={string.Join(",", detailPKIds)} 批量发送邮件通知给客户 处理异常,原因:{ex.Message}");
new EmailNoticeHelper().SendEmailNotice($"taskid={detailPKIds.FirstOrDefault()} Advisory 换船提醒 转发通知邮件失败", $"taskid={detailPKIds.FirstOrDefault()} 换船提醒 detailPKIds={string.Join(",", detailPKIds)} 批量发送邮件通知给客户 处理异常,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
}
return result;
}
#endregion
/// <summary>
/// 生成并转发通知邮件
/// </summary>
/// <param name="model"></param>
/// <param name="bookingOrderList"></param>
/// <param name="bookingContactList"></param>
/// <param name="taskBaskInfo"></param>
/// <returns></returns>
private async Task<TaskManageOrderResultDto> GenerateSendEmail(TaskRouteChangeAdvisoryInfo model,List<BookingOrder> bookingOrderList,List<BookingOrderContact> bookingContactList, TaskBaseInfo taskBaskInfo)
{
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 = $"Advisory{model.EMAIL_SUBJECT}";
//提取当前公共邮箱的配置
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("advisory_route_change_template") && x.TenantId == UserManager.TENANT_ID);
if (printTemplate == null)
{
throw Oops.Bah(BookingErrorCode.BOOK115);
}
//读取邮件模板并填充数据
string emailHtml = GenerateSendEmailHtml(model, 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>()
};
//如果配置了租户参数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.LogInformation($"生成请求邮件参数,结果:{JSON.Serialize(emailApiUserDefinedDto)}");
TaskFileInfo fileInfo = null;
if (taskBaskInfo.TASK_BASE_TYPE == TaskBaseTypeEnum.ROUTE_CUT_CHANGE.ToString())
{
fileInfo = _taskFileRepository.AsQueryable().Filter(null, true).Where(a => a.TASK_PKID == taskBaskInfo.PK_ID && a.FILE_CATEGORY.Contains("ADVISORY"))
.OrderByDescending(a => a.CreatedTime).First();
}
if (fileInfo == null)
{
throw Oops.Oh($"提取文件失败,不能发送邮件");
}
_logger.LogInformation($"获取订舱附件地址,结果:{fileInfo.FILE_PATH}");
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
string filePath = Path.Combine(dirAbs, fileInfo.FILE_PATH);
//推送邮件
var emailRlt = await PushEmail(emailApiUserDefinedDto, filePath);
_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} Advisory 换船提醒 转发通知邮件失败", $"taskid={model.TASK_ID} 换船提醒 转发通知邮件失败,原因:{emailRlt.msg}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
}
}
catch (Exception ex)
{
}
return result;
}
#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>
public async Task<string> GenerateSendEmailHtml(TaskRouteChangeAdvisoryInfo model, 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.EMAIL_SUBJECT))
{
baseHtml = baseHtml.Replace("#AdvisorySubject#", model.EMAIL_SUBJECT);
}
else
{
baseHtml = baseHtml.Replace("#AdvisorySubject#", "");
}
if (!string.IsNullOrWhiteSpace(tenantName))
{
baseHtml = baseHtml.Replace("#TenantCompanyName#", tenantName);
}
else
{
baseHtml = baseHtml.Replace("#TenantCompanyName#", "");
}
HtmlDocument html = new HtmlDocument();
html.LoadHtml(baseHtml);
HtmlNode baseTable = html.DocumentNode.SelectNodes("//table[@class='billno-table']").FirstOrDefault();
if (baseTable == null)
throw Oops.Oh($"读取邮件模板格式错误定位base-table失败");
//var baseTrList = baseTable.SelectNodes(".//tr");
bookingOrderList.ForEach(b =>
{
baseTable.ChildNodes.Add(HtmlNode.CreateNode($"<tr><td>{b.MBLNO}</td></tr>"));
});
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>
private async Task<CommonWebApiResult> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto, string filePath)
{
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 请联系管理员");
System.IO.FileStream file = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
int SplitSize = 5242880;//5M分片长度
int index = 1; //序号 第几片
long StartPosition = 5242880 * (index - 1);
long lastLens = file.Length - StartPosition;//真不知道怎么起命了,就这样吧
if (lastLens < 5242880)
{
SplitSize = (int)lastLens;
}
byte[] heByte = new byte[SplitSize];
file.Seek(StartPosition, SeekOrigin.Begin);
//第一个参数是 起始位置
file.Read(heByte, 0, SplitSize);
//第三个参数是 读取长度(剩余长度)
file.Close();
string base64Str = Convert.ToBase64String(heByte);
string newFileName = Path.GetFileName(filePath);
if (newFileName.Length > 12)
newFileName = $"{Path.GetFileName(filePath).Substring(0, 12)}{Path.GetExtension(filePath)}";
emailApiUserDefinedDto.Attaches.Add(new AttachesInfo
{
AttachName = newFileName,
AttachContent = base64Str
});
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($"邮件上传完成 上传文件大小:{heByte.Length} 用时:{timeDiff}ms.,");
_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
}
}