|
|
using Furion;
|
|
|
using Furion.DependencyInjection;
|
|
|
using Furion.DynamicApiController;
|
|
|
using Furion.FriendlyException;
|
|
|
using Furion.JsonSerialization;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using HtmlAgilityPack;
|
|
|
using Mapster;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Myshipping.Application;
|
|
|
using Myshipping.Application.ConfigOption;
|
|
|
using Myshipping.Application.Entity;
|
|
|
using Myshipping.Application.Enum;
|
|
|
using Myshipping.Application.Helper;
|
|
|
using Myshipping.Application.Service.BookingSlot.Dto;
|
|
|
using Myshipping.Application.Service.TaskManagePlat.Interface;
|
|
|
using Myshipping.Core;
|
|
|
using Myshipping.Core.Entity;
|
|
|
using Myshipping.Core.Helper;
|
|
|
using Myshipping.Core.Service;
|
|
|
using Newtonsoft.Json;
|
|
|
using Npoi.Mapper;
|
|
|
using NPOI.OpenXmlFormats.Wordprocessing;
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
using Org.BouncyCastle.Asn1.Tsp;
|
|
|
using Org.BouncyCastle.Crypto;
|
|
|
using SqlSugar;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Drawing;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Net.Http;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
namespace Myshipping.Application
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 截止时间变更
|
|
|
/// </summary>
|
|
|
[ApiDescriptionSettings("Application", Name = "TaskManageCutDateChange", Order = 10)]
|
|
|
public class TaskManageCutDateChangeService : ITaskManageCutDateChangeService, IDynamicApiController, ITransient
|
|
|
{
|
|
|
private readonly SqlSugarRepository<TaskCutDateChangeInfo> _taskCutDateChangeInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskCutDateChangeDetailInfo> _taskCutDateChangeDetailInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
|
|
|
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;
|
|
|
private readonly INamedServiceProvider<IBookingOrderService> _namedBookingOrderServiceProvider;
|
|
|
private readonly SqlSugarRepository<BookingSlotBase> _bookingSlotBaseRepository;
|
|
|
private readonly INamedServiceProvider<ITaskCautionNoticeService> _namedTaskCautionNoticeServiceProvider;
|
|
|
|
|
|
|
|
|
public TaskManageCutDateChangeService(SqlSugarRepository<TaskCutDateChangeInfo> taskCutDateChangeInfoRepository,
|
|
|
SqlSugarRepository<TaskCutDateChangeDetailInfo> taskCutDateChangeDetailInfoRepository,
|
|
|
SqlSugarRepository<BookingOrderContact> bookingOrderContactRepository,
|
|
|
SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
|
|
|
SqlSugarRepository<SysUser> sysUserRepository,
|
|
|
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount,
|
|
|
SqlSugarRepository<BookingPrintTemplate> repPrintTemplate,
|
|
|
ILogger<TaskManageCutDateChangeService> logger,
|
|
|
ISysCacheService cache,
|
|
|
INamedServiceProvider<IBookingOrderService> namedBookingOrderServiceProvider,
|
|
|
INamedServiceProvider<ITaskCautionNoticeService> namedTaskCautionNoticeServiceProvider,
|
|
|
SqlSugarRepository<BookingSlotBase> bookingSlotBaseRepository,
|
|
|
SqlSugarRepository<BookingOrder> bookingOrderRepository)
|
|
|
{
|
|
|
_taskCutDateChangeInfoRepository = taskCutDateChangeInfoRepository;
|
|
|
_taskCutDateChangeDetailInfoRepository = taskCutDateChangeDetailInfoRepository;
|
|
|
_taskBaseRepository = taskBaseRepository;
|
|
|
_bookingOrderRepository = bookingOrderRepository;
|
|
|
_bookingOrderContactRepository = bookingOrderContactRepository;
|
|
|
_sysUserRepository = sysUserRepository;
|
|
|
_djyUserMailAccount = djyUserMailAccount;
|
|
|
_repPrintTemplate = repPrintTemplate;
|
|
|
_namedBookingOrderServiceProvider = namedBookingOrderServiceProvider;
|
|
|
_bookingSlotBaseRepository = bookingSlotBaseRepository;
|
|
|
_namedTaskCautionNoticeServiceProvider = namedTaskCautionNoticeServiceProvider;
|
|
|
|
|
|
_logger = logger;
|
|
|
_cache = cache;
|
|
|
}
|
|
|
|
|
|
#region 获取截止时间变更详情
|
|
|
/// <summary>
|
|
|
/// 获取截止时间变更详情
|
|
|
/// </summary>
|
|
|
/// <param name="pkId">截止时间变更主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageCutDate/GetInfo")]
|
|
|
public async Task<List<TaskCutDateChangeShowDto>> GetInfo(string pkId)
|
|
|
{
|
|
|
List<TaskCutDateChangeShowDto> list = new List<TaskCutDateChangeShowDto>();
|
|
|
|
|
|
var cutChangeOrder = _taskCutDateChangeInfoRepository.AsQueryable().First(a => a.PK_ID == pkId);
|
|
|
|
|
|
if (cutChangeOrder == null)
|
|
|
throw Oops.Oh($"截止时间变更主键{pkId}无法获取业务信息");
|
|
|
|
|
|
var detailList = _taskCutDateChangeDetailInfoRepository.AsQueryable()
|
|
|
.Where(a => a.P_ID == pkId).ToList();
|
|
|
|
|
|
if (detailList.Count > 0)
|
|
|
{
|
|
|
list = detailList.OrderBy(p => p.MBL_NO).Select(p =>
|
|
|
{
|
|
|
TaskCutDateChangeShowDto model = p.Adapt<TaskCutDateChangeShowDto>();
|
|
|
|
|
|
model.NoticeDate = cutChangeOrder.NOTICE_DATE;
|
|
|
model.Carrier = cutChangeOrder.CARRIER;
|
|
|
|
|
|
return model;
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 通过任务主键获取截止时间变更详情
|
|
|
/// <summary>
|
|
|
/// 通过任务主键获取截止时间变更详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPkId">截止时间变更任务主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManageCutDate/GetInfoByTaskId")]
|
|
|
public async Task<List<TaskCutDateChangeShowDto>> GetInfoByTaskId(string taskPkId)
|
|
|
{
|
|
|
List<TaskCutDateChangeShowDto> list = new List<TaskCutDateChangeShowDto>();
|
|
|
|
|
|
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId);
|
|
|
|
|
|
if (taskBase == null)
|
|
|
throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
var cutChangeOrder = _taskCutDateChangeInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID);
|
|
|
|
|
|
if (cutChangeOrder == null)
|
|
|
throw Oops.Oh($"截止时间变更主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
var detailList = _taskCutDateChangeDetailInfoRepository.AsQueryable()
|
|
|
.Where(a => a.P_ID == cutChangeOrder.PK_ID).ToList();
|
|
|
|
|
|
if (detailList.Count > 0)
|
|
|
{
|
|
|
list = detailList.OrderBy(p => p.MBL_NO).Select(p =>
|
|
|
{
|
|
|
TaskCutDateChangeShowDto model = p.Adapt<TaskCutDateChangeShowDto>();
|
|
|
|
|
|
model.NoticeDate = cutChangeOrder.NOTICE_DATE;
|
|
|
model.Carrier = cutChangeOrder.CARRIER;
|
|
|
|
|
|
return model;
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 重新处理截止时间变更任务
|
|
|
/// <summary>
|
|
|
/// 重新处理截止时间变更任务
|
|
|
/// 对未匹配订舱订单的任务记录,重新对应订单订单
|
|
|
/// </summary>
|
|
|
/// <param name="taskPkId">截止时间变更任务主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
public async Task<TaskManageOrderResultDto> SearchAndConnectBookingInfo(string taskPkId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId);
|
|
|
|
|
|
if (taskBase == null)
|
|
|
throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
var cutDateChange = _taskCutDateChangeInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID);
|
|
|
|
|
|
if (cutDateChange == null)
|
|
|
throw Oops.Oh($"截止时间变更主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
var detailList = _taskCutDateChangeDetailInfoRepository.AsQueryable()
|
|
|
.Where(a => a.P_ID == cutDateChange.PK_ID).ToList();
|
|
|
|
|
|
//如果都有订单订单记录,则提示错误不进行对应
|
|
|
if (!detailList.Any(t => !t.BOOKING_ID.HasValue))
|
|
|
{
|
|
|
throw Oops.Oh($"当前截止时间变更已有匹配的订舱订单,不能执行操作");
|
|
|
}
|
|
|
|
|
|
var mblList = detailList.Select(a => a.MBL_NO).Distinct().ToList();
|
|
|
|
|
|
var bookingList = _bookingOrderRepository.AsQueryable().Filter(null, true)
|
|
|
.Where(a => mblList.Contains(a.MBLNO) && a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0)).ToList();
|
|
|
|
|
|
if (bookingList.Count == 0)
|
|
|
throw Oops.Oh($"提单号未提取有效的订舱订单");
|
|
|
|
|
|
List<string> msgList = new List<string>();
|
|
|
|
|
|
detailList.ForEach(async t =>
|
|
|
{
|
|
|
//只处理没有订舱ID的记录
|
|
|
if (!t.BOOKING_ID.HasValue)
|
|
|
{
|
|
|
var currBook = bookingList.FirstOrDefault(p => p.MBLNO == t.MBL_NO);
|
|
|
|
|
|
if (currBook != null)
|
|
|
{
|
|
|
t.BOOKING_ID = currBook.Id;
|
|
|
t.UpdatedUserId = UserManager.UserId;
|
|
|
t.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
//更新任务BC
|
|
|
await _taskCutDateChangeDetailInfoRepository.AsUpdateable(t).UpdateColumns(it => new
|
|
|
{
|
|
|
it.BOOKING_ID,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgList.Add(t.MBL_NO);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
if (msgList.Count > 0)
|
|
|
throw Oops.Oh($"提单号{(string.Join(",", msgList.ToArray()))}未提取有效的订舱订单");
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "成功";
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 推送及时消息
|
|
|
/// <summary>
|
|
|
/// 推送及时消息
|
|
|
/// </summary>
|
|
|
/// <param name="taskPkId">截止时间任务主键</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
public async Task<TaskManageOrderResultDto> SendInstantMessage(string taskPkId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId);
|
|
|
|
|
|
if (taskBase == null)
|
|
|
throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
var cutDateChange = _taskCutDateChangeInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID);
|
|
|
|
|
|
if (cutDateChange == null)
|
|
|
throw Oops.Oh($"截止时间变更主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
var detailList = _taskCutDateChangeDetailInfoRepository.AsQueryable()
|
|
|
.Where(a => a.P_ID == cutDateChange.PK_ID).ToList();
|
|
|
|
|
|
//如果都有订单订单记录,则提示错误不进行对应
|
|
|
if (!detailList.Any(t => t.BOOKING_ID.HasValue))
|
|
|
{
|
|
|
throw Oops.Oh($"当前截止时间变更没有匹配的订舱订单,不能执行操作");
|
|
|
}
|
|
|
|
|
|
var ids = detailList.Where(a => a.BOOKING_ID.HasValue).Select(a => a.BOOKING_ID.Value).ToList();
|
|
|
|
|
|
var bookingList = _bookingOrderRepository.AsQueryable().Filter(null, true)
|
|
|
.Where(a => ids.Contains(a.Id) && a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0)).ToList();
|
|
|
|
|
|
if (bookingList.Count == 0)
|
|
|
throw Oops.Oh($"提单号未提取有效的订舱订单");
|
|
|
|
|
|
Dictionary<string, List<string>> msgList = new Dictionary<string, List<string>>();
|
|
|
|
|
|
msgList = bookingList.GroupBy(a => a.OP).Select(a =>
|
|
|
{
|
|
|
var currList = a.ToList();
|
|
|
|
|
|
return new { Key = a.Key, list = currList.Select(a => a.MBLNO).ToList() };
|
|
|
}).ToDictionary(a => a.Key, b => b.list);
|
|
|
|
|
|
if (msgList.Count > 0)
|
|
|
{
|
|
|
msgList.ForEach(t =>
|
|
|
{
|
|
|
DingTalkGroupHelper.SendDingTalkGroupMessage("KangqianNotify", "截止时间变更消息", $"@{t.Key} 收到如下提单号{(string.Join(",", t.Value.ToArray()))}的截止时间变更消息");
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (detailList.Any(t => !t.BOOKING_ID.HasValue))
|
|
|
throw Oops.Oh($"提单号{(string.Join(",", detailList.Where(t => !t.BOOKING_ID.HasValue).Select(t => t.MBL_NO).ToArray()))}未提取有效的订舱订单");
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "成功";
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#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 = await QueryBookingOrder(taskPKId);
|
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 检索对应的订舱记录完成,结果:{JSON.Serialize(queryRlt)}");
|
|
|
|
|
|
if (queryRlt.succ)
|
|
|
{
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 检索对应的订舱记录成功,触发订舱的截止时间更新");
|
|
|
|
|
|
//更新订舱的截单时间
|
|
|
await UpdateBookingOrderCutDate(taskPKId);
|
|
|
}
|
|
|
|
|
|
await UpdateBookingSlotCutDate(taskPKId);
|
|
|
|
|
|
//如果没有配置批量,则按单票发送邮件
|
|
|
var rlt = await 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} 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.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") && x.TenantId == UserManager.TENANT_ID);
|
|
|
|
|
|
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 (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.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
|
|
|
|
|
|
#region 更新订舱截止时间
|
|
|
/// <summary>
|
|
|
/// 更新订舱截止时间
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">截止时间变更任务主键</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task UpdateBookingOrderCutDate(string taskPKId)
|
|
|
{
|
|
|
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}无法获取业务信息");
|
|
|
|
|
|
if (!entityInfo.BOOKING_ID.HasValue)
|
|
|
throw Oops.Oh($"截止时间变更主键{taskPKId} mblno={entityInfo.MBL_NO} 没有匹配的订舱记录,更新截止时间失败");
|
|
|
|
|
|
var bookingId = entityInfo.BOOKING_ID.Value;
|
|
|
|
|
|
//通过船名航次取是主单的订舱记录列表
|
|
|
var bookingInfo = _bookingOrderRepository.AsQueryable().Filter(null, true).First(a => a.Id == bookingId);
|
|
|
|
|
|
var detailInfo = _taskCutDateChangeDetailInfoRepository.AsQueryable().Filter(null, true).First(a => a.P_ID == entityInfo.PK_ID);
|
|
|
|
|
|
var oldOrder = bookingInfo.Adapt<BookingOrder>();
|
|
|
|
|
|
_logger.LogInformation($"更新订舱相关的截单时间 JSON={JSON.Serialize(detailInfo)}");
|
|
|
|
|
|
if (detailInfo.VGM_CUT.HasValue)
|
|
|
bookingInfo.CLOSEVGMDATE = detailInfo.VGM_CUT.Value;
|
|
|
|
|
|
if (detailInfo.CY_CUTOFF.HasValue)
|
|
|
bookingInfo.CLOSINGDATE = detailInfo.CY_CUTOFF.Value;
|
|
|
|
|
|
if (detailInfo.SI_CUTOFF.HasValue)
|
|
|
bookingInfo.CLOSEDOCDATE = detailInfo.SI_CUTOFF.Value;
|
|
|
|
|
|
_bookingOrderRepository.AsUpdateable(bookingInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.CLOSEVGMDATE,
|
|
|
it.CLOSINGDATE,
|
|
|
it.CLOSEDOCDATE
|
|
|
}).ExecuteCommand();
|
|
|
|
|
|
// 保存日志
|
|
|
var bookingOrderService = _namedBookingOrderServiceProvider.GetService<ITransient>(nameof(BookingOrderService));
|
|
|
bookingOrderService.SaveLog(bookingInfo, oldOrder, "截止时间变更");
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"截止时间变更主键{taskPKId} mblno={entityInfo.MBL_NO} 更新订舱完毕");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"taskid={taskPKId} 截止时间变更更新订舱失败");
|
|
|
|
|
|
new EmailNoticeHelper().SendEmailNotice($"taskid={taskPKId} 截止时间变更更新订舱失败", $"taskid={taskPKId} 截止时间变更更新订舱失败,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
|
|
|
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 更新舱位截止时间
|
|
|
/// <summary>
|
|
|
/// 更新舱位截止时间
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">截止时间变更任务主键</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task UpdateBookingSlotCutDate(string taskPKId)
|
|
|
{
|
|
|
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 detailInfo = _taskCutDateChangeDetailInfoRepository.AsQueryable().Filter(null, true).First(a => a.P_ID == entityInfo.PK_ID);
|
|
|
|
|
|
|
|
|
//判断是否有舱位,需要更新舱位
|
|
|
var slotOrder = _bookingSlotBaseRepository.AsQueryable().Filter(null, true)
|
|
|
.First(x => entityInfo.MBL_NO.Equals(x.SLOT_BOOKING_NO)
|
|
|
&& x.IsDeleted == false && x.TenantId == UserManager.TENANT_ID);
|
|
|
|
|
|
var oldOrder = slotOrder.Adapt<BookingSlotBase>();
|
|
|
|
|
|
_logger.LogInformation($"更新订舱相关的截单时间 JSON={JSON.Serialize(entityInfo)}");
|
|
|
|
|
|
if (detailInfo.VGM_CUT.HasValue)
|
|
|
slotOrder.VGM_SUBMISSION_CUT_DATE = detailInfo.VGM_CUT.Value;
|
|
|
|
|
|
if (detailInfo.CY_CUTOFF.HasValue)
|
|
|
slotOrder.CY_CUT_DATE = detailInfo.CY_CUTOFF;
|
|
|
|
|
|
if (detailInfo.SI_CUTOFF.HasValue)
|
|
|
slotOrder.SI_CUT_DATE = detailInfo.SI_CUTOFF;
|
|
|
|
|
|
if (detailInfo.MDGF_CUT.HasValue)
|
|
|
slotOrder.MDGF_CUT_DATE = detailInfo.MDGF_CUT;
|
|
|
|
|
|
if (detailInfo.MANIFEST_CUT.HasValue)
|
|
|
slotOrder.MANIFEST_CUT_DATE = detailInfo.MANIFEST_CUT;
|
|
|
|
|
|
_bookingSlotBaseRepository.AsUpdateable(slotOrder).UpdateColumns(it => new
|
|
|
{
|
|
|
it.VGM_SUBMISSION_CUT_DATE,
|
|
|
it.CY_CUT_DATE,
|
|
|
it.SI_CUT_DATE,
|
|
|
it.MDGF_CUT_DATE,
|
|
|
it.MANIFEST_CUT_DATE
|
|
|
}).ExecuteCommand();
|
|
|
|
|
|
await ComparePushCaucation(slotOrder, oldOrder);
|
|
|
|
|
|
_logger.LogInformation($"截止时间变更主键{taskPKId} mblno={entityInfo.MBL_NO} 更新舱位完毕");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"taskid={taskPKId} 截止时间变更更新舱位失败");
|
|
|
|
|
|
new EmailNoticeHelper().SendEmailNotice($"taskid={taskPKId} 截止时间变更更新舱位失败", $"taskid={taskPKId} 截止时间变更更新舱位失败,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
|
|
|
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 异步判断是否需要重要提醒,并发送钉钉通知
|
|
|
/// <summary>
|
|
|
/// 异步判断是否需要重要提醒,并发送钉钉通知
|
|
|
/// </summary>
|
|
|
/// <param name="slotInfo">新修改舱位详情</param>
|
|
|
/// <param name="oldSlotInfo">修改前舱位详情</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task ComparePushCaucation(BookingSlotBase slotInfo, BookingSlotBase oldSlotInfo)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
CautionNoticeTaskWholeShipDto cautionNoticeTaskWholeShipDto = new CautionNoticeTaskWholeShipDto
|
|
|
{
|
|
|
Carrier = slotInfo.CARRIERID,
|
|
|
MBLNo = slotInfo.SLOT_BOOKING_NO
|
|
|
};
|
|
|
|
|
|
bool isDiff = false;
|
|
|
|
|
|
string srcVesselVoyno = $"{oldSlotInfo.VESSEL}/{oldSlotInfo.VOYNO}";
|
|
|
string targetVesselVoyno = $"{slotInfo.VESSEL}/{slotInfo.VOYNO}";
|
|
|
|
|
|
if (!srcVesselVoyno.Equals(targetVesselVoyno, StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
cautionNoticeTaskWholeShipDto.VesselOldVal = oldSlotInfo.VESSEL;
|
|
|
cautionNoticeTaskWholeShipDto.VesselNewVal = slotInfo.VESSEL;
|
|
|
cautionNoticeTaskWholeShipDto.VoynoOldVal = oldSlotInfo.VOYNO;
|
|
|
cautionNoticeTaskWholeShipDto.VoynoNewVal = slotInfo.VOYNO;
|
|
|
|
|
|
cautionNoticeTaskWholeShipDto.IsVesselChange = true;
|
|
|
|
|
|
isDiff = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
cautionNoticeTaskWholeShipDto.VesselOldVal = oldSlotInfo.VESSEL;
|
|
|
cautionNoticeTaskWholeShipDto.VoynoOldVal = oldSlotInfo.VOYNO;
|
|
|
}
|
|
|
|
|
|
|
|
|
string srcCarrierType = oldSlotInfo.CARRIAGE_TYPE ?? "";
|
|
|
string targetCarrierType = slotInfo.CARRIAGE_TYPE ?? "";
|
|
|
|
|
|
//如果原来是直航现在变成了中转需要做重要提醒
|
|
|
if (!srcCarrierType.Equals(targetCarrierType, StringComparison.OrdinalIgnoreCase)
|
|
|
&& srcCarrierType.Equals("DIRECT_SHIP", StringComparison.OrdinalIgnoreCase)
|
|
|
&& targetCarrierType.Equals("TRANSFER_SHIP", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
cautionNoticeTaskWholeShipDto.DirectToTransOldVal = "直达";
|
|
|
cautionNoticeTaskWholeShipDto.DirectToTransNewVal = "中转";
|
|
|
|
|
|
cautionNoticeTaskWholeShipDto.IsTransfer = true;
|
|
|
|
|
|
isDiff = true;
|
|
|
}
|
|
|
|
|
|
string srcVGMCut = oldSlotInfo.VGM_SUBMISSION_CUT_DATE.HasValue? oldSlotInfo.VGM_SUBMISSION_CUT_DATE.Value.ToString("yyyy-MM-dd HH:mm:ss"):"";
|
|
|
string targeVGMCut = slotInfo.VGM_SUBMISSION_CUT_DATE.HasValue ? slotInfo.VGM_SUBMISSION_CUT_DATE.Value.ToString("yyyy-MM-dd HH:mm:ss") : "";
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(srcVGMCut) && !string.IsNullOrWhiteSpace(targeVGMCut) && !srcVGMCut.Equals(targeVGMCut))
|
|
|
{
|
|
|
DateTime srcVGMCutDate = DateTime.Parse(srcVGMCut);
|
|
|
DateTime targeVGMCutDate = DateTime.Parse(targeVGMCut);
|
|
|
|
|
|
if (srcVGMCutDate > targeVGMCutDate)
|
|
|
{
|
|
|
cautionNoticeTaskWholeShipDto.VGMCutOldVal = srcVGMCutDate.ToString("yyyy-MM-dd HH:mm");
|
|
|
cautionNoticeTaskWholeShipDto.VGMCutNewVal = targeVGMCutDate.ToString("yyyy-MM-dd HH:mm");
|
|
|
|
|
|
cautionNoticeTaskWholeShipDto.IsCutDateAdvanced = true;
|
|
|
|
|
|
isDiff = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
string srcSICut = oldSlotInfo.SI_CUT_DATE.HasValue ? oldSlotInfo.SI_CUT_DATE.Value.ToString("yyyy-MM-dd HH:mm:ss") : "";
|
|
|
string targeSICut = slotInfo.SI_CUT_DATE.HasValue ? slotInfo.SI_CUT_DATE.Value.ToString("yyyy-MM-dd HH:mm:ss") : "";
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(srcSICut) && !string.IsNullOrWhiteSpace(targeSICut) && !srcSICut.Equals(targeSICut))
|
|
|
{
|
|
|
DateTime srcSICutDate = DateTime.Parse(srcSICut);
|
|
|
DateTime targeSICutDate = DateTime.Parse(targeSICut);
|
|
|
|
|
|
//如果新给的SI截止时间,需要推送通知
|
|
|
if (srcSICutDate > targeSICutDate)
|
|
|
{
|
|
|
cautionNoticeTaskWholeShipDto.SICutOldVal = srcSICutDate.ToString("yyyy-MM-dd HH:mm");
|
|
|
cautionNoticeTaskWholeShipDto.SICutNewVal = targeSICutDate.ToString("yyyy-MM-dd HH:mm");
|
|
|
|
|
|
cautionNoticeTaskWholeShipDto.IsCutDateAdvanced = true;
|
|
|
|
|
|
isDiff = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (isDiff)
|
|
|
{
|
|
|
//这里增加判断是否截止时间提前,然后推送钉钉消息
|
|
|
var name = _namedTaskCautionNoticeServiceProvider
|
|
|
.GetService<ITransient>(nameof(TaskCautionNoticeService));
|
|
|
|
|
|
var wholeShipRlt = await name.GenerateWholeShipCaucation(cautionNoticeTaskWholeShipDto, slotInfo);
|
|
|
}
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"MBLNO={slotInfo.SLOT_BOOKING_NO} 异步判断是否需要重要提醒,并发送钉钉通知异常,原因:{ex.Message}");
|
|
|
|
|
|
new EmailNoticeHelper().SendEmailNotice($"MBLNO={slotInfo.SLOT_BOOKING_NO} 异步判断是否需要重要提醒,并发送钉钉通知异常", $"MBLNO={slotInfo.SLOT_BOOKING_NO} 异步判断是否需要重要提醒,并发送钉钉通知异常,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
|
|
|
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|