From 7f3e9b42b8ba40fb1f0efd33cec2450fbb478181 Mon Sep 17 00:00:00 2001 From: wanghaomei <86whm@163.com> Date: Thu, 28 Mar 2024 16:20:21 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E7=A7=9F=E6=88=B7=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Myshipping.Core/Myshipping.Core.xml | 84 +++++++++++++-- .../DjyTenantParam/DjyTenantParamService.cs | 101 +++++++++++++++--- .../DjyTenantParam/Dto/DjyTenantParamInput.cs | 28 ++--- .../Dto/DjyTenantParamOutput.cs | 7 +- .../Dto/DjyTenantParamValueOutput.cs | 41 +++++++ 5 files changed, 223 insertions(+), 38 deletions(-) diff --git a/Myshipping.Core/Myshipping.Core.xml b/Myshipping.Core/Myshipping.Core.xml index e7eb3e4d..a4775205 100644 --- a/Myshipping.Core/Myshipping.Core.xml +++ b/Myshipping.Core/Myshipping.Core.xml @@ -12561,6 +12561,13 @@ 获取租户参数类别 + 准备废弃,使用/DJYTenantParam/page替代 + + + + + + 分页获取租户参数类别 @@ -12590,7 +12597,14 @@ - 获取参数 + 获取参数 + 准备废弃,使用/DJYTenantParam/PageParamValue替代 + + + + + + 分页获取参数值 @@ -12713,11 +12727,6 @@ 租户参数类别表查询输入参数 - - - 主键Id - - 类别代码 @@ -12733,14 +12742,19 @@ 业务大类 - + - 备注 + 租户参数值查询输入参数 - + - 排序 + 类别代码 + + + + + 租户id @@ -12768,6 +12782,11 @@ 业务大类 + + + 业务大类名称 + + 备注 @@ -12778,6 +12797,51 @@ 排序 + + + 列表输出 + + + + + 参数类别 + + + + + 类别名称 + + + + + 租户id + + + + + 租户名称 + + + + + 参数值 + + + + + 参数值名称 + + + + + 备注 + + + + + 排序 + + 用户自定义配置服务 diff --git a/Myshipping.Core/Service/DjyTenantParam/DjyTenantParamService.cs b/Myshipping.Core/Service/DjyTenantParam/DjyTenantParamService.cs index 5ab9642a..52e3e68e 100644 --- a/Myshipping.Core/Service/DjyTenantParam/DjyTenantParamService.cs +++ b/Myshipping.Core/Service/DjyTenantParam/DjyTenantParamService.cs @@ -25,13 +25,19 @@ namespace Myshipping.Core.Service private readonly SqlSugarRepository _valuerep; private readonly ILogger _logger; private readonly ISysCacheService _cache; - public DjyTenantParamService(SqlSugarRepository rep, SqlSugarRepository itemrep, SqlSugarRepository valuerep, ISysCacheService cache, ILogger logger) + private readonly SqlSugarRepository _repTenant; + public DjyTenantParamService(SqlSugarRepository rep, + SqlSugarRepository itemrep, + SqlSugarRepository valuerep, + ISysCacheService cache, ILogger logger, + SqlSugarRepository repTenant) { _rep = rep; _logger = logger; _itemrep = itemrep; _valuerep = valuerep; _cache = cache; + _repTenant = repTenant; } #region 类别 @@ -119,6 +125,7 @@ namespace Myshipping.Core.Service /// /// 获取租户参数类别 + /// 准备废弃,使用/DJYTenantParam/page替代 /// /// [HttpGet("/DJYTenantParam/list")] @@ -126,6 +133,31 @@ namespace Myshipping.Core.Service { return await _rep.AsQueryable().WhereIF(!string.IsNullOrEmpty(Type), x => x.Type == Type).WhereIF(!string.IsNullOrEmpty(ParaName), x => x.ParaName.Contains(ParaName)).OrderBy(x => x.Sort).ToListAsync(); } + + /// + /// 分页获取租户参数类别 + /// + /// + [HttpGet("/DJYTenantParam/page")] + public async Task> Page(QueryDJYTenantParamInput input) + { + var list = await _rep.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(input.Type), x => x.Type == input.Type) + .WhereIF(!string.IsNullOrEmpty(input.ParaCode), x => x.ParaCode == input.ParaCode) + .WhereIF(!string.IsNullOrEmpty(input.ParaName), x => x.ParaName.Contains(input.ParaName)) + .OrderBy(x => x.Sort) + .ToPagedListAsync(input.PageNo, input.PageSize); + + var rtn = list.Adapt>(); + var dict = await _cache.GetAllDictData(); + foreach (var item in rtn.Items) + { + var d = dict.FirstOrDefault(x => x.TypeCode == "tenant_param_group" && x.Code == item.Type); + item.TypeName = d.Value; + } + + return rtn; + } #endregion #region 参数 @@ -231,7 +263,8 @@ namespace Myshipping.Core.Service #region 值 /// - /// 获取参数 + /// 获取参数 + /// 准备废弃,使用/DJYTenantParam/PageParamValue替代 /// /// [HttpGet("/DJYTenantParam/getParamValue")] @@ -239,6 +272,44 @@ namespace Myshipping.Core.Service { return await _valuerep.AsQueryable().Filter(null, true).WhereIF(paraCode != null, x => x.ParaCode == paraCode).OrderBy(x => x.Sort).ToListAsync(); } + + /// + /// 分页获取参数值 + /// + /// + [HttpGet("/DJYTenantParam/PageParamValue")] + public async Task> PageParamValue(QueryTenantParamValueInput input) + { + var list = await _valuerep.AsQueryable().Filter(null, true) + .WhereIF(!string.IsNullOrEmpty(input.ParaCode), x => x.ParaCode == input.ParaCode) + .WhereIF(input.TenantId.HasValue, x => x.TenantId == input.TenantId) + .OrderBy(x => x.Sort) + .ToPagedListAsync(input.PageNo, input.PageSize); + + + var rtn = list.Adapt>(); + var listParam = await _rep.AsQueryable().ToListAsync(); + var listParamItem = await _itemrep.AsQueryable().ToListAsync(); + var listTenant = await _repTenant.AsQueryable().Select(x => new { x.Id, x.Name }).ToListAsync(); + foreach (var item in rtn.Items) + { + var p = listParam.FirstOrDefault(x => x.ParaCode == item.ParaCode); + item.ParaName = p.ParaName; + + var t = listTenant.FirstOrDefault(x => x.Id == item.TenantId); + item.TenantName = t.Name; + + var it= listParamItem.FirstOrDefault(x=>x.ParaCode == item.ParaCode&&x.ItemCode==item.ItemCode); + if (it != null) + { + item.ItemCodeName = it.ItemName; + } + } + + return rtn; + + } + /// /// 增加参数 /// @@ -323,19 +394,19 @@ namespace Myshipping.Core.Service [NonAction] public async Task> GetParaCodeWithValue(string[] paraCodes) { - List result = await _rep.AsQueryable() - .Filter(null, true) - .LeftJoin((t1, t2) => t1.ParaCode == t2.ParaCode) - .Where((t1, t2) => t2.TenantId == UserManager.TENANT_ID) - .WhereIF(paraCodes?.Any() == true, (t1, t2) => paraCodes.Contains(t1.ParaCode)) - .Select((t1, t2) => new DjyTenantParamValueOutput() - { - ParaCode = t1.ParaCode, - ParaName = t1.ParaName, - ParaType = t1.Type, - ParaValue = t2.ItemCode - }) - .ToListAsync(); + List result = await _rep.AsQueryable() + .Filter(null, true) + .LeftJoin((t1, t2) => t1.ParaCode == t2.ParaCode) + .Where((t1, t2) => t2.TenantId == UserManager.TENANT_ID) + .WhereIF(paraCodes?.Any() == true, (t1, t2) => paraCodes.Contains(t1.ParaCode)) + .Select((t1, t2) => new DjyTenantParamValueOutput() + { + ParaCode = t1.ParaCode, + ParaName = t1.ParaName, + ParaType = t1.Type, + ParaValue = t2.ItemCode + }) + .ToListAsync(); return result; } #endregion diff --git a/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamInput.cs b/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamInput.cs index 6cd5b9e5..c6baccef 100644 --- a/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamInput.cs +++ b/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamInput.cs @@ -73,12 +73,7 @@ namespace Myshipping.Core.Service /// 租户参数类别表查询输入参数 /// public class QueryDJYTenantParamInput : PageInputBase - { - /// - /// 主键Id - /// - public virtual long Id { get; set; } - + { /// /// 类别代码 /// @@ -94,15 +89,24 @@ namespace Myshipping.Core.Service /// public virtual string Type { get; set; } + } + + + /// + /// 租户参数值查询输入参数 + /// + public class QueryTenantParamValueInput : PageInputBase + { /// - /// 备注 + /// 类别代码 /// - public virtual string Remark { get; set; } - + public virtual string ParaCode { get; set; } + /// - /// 排序 + /// 租户id /// - public virtual int Sort { get; set; } - + public long? TenantId { get; set; } + + } } diff --git a/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamOutput.cs b/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamOutput.cs index a5931a4b..dfac0ca6 100644 --- a/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamOutput.cs +++ b/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamOutput.cs @@ -26,7 +26,12 @@ namespace Myshipping.Core.Service /// 业务大类 /// public string Type { get; set; } - + + /// + /// 业务大类名称 + /// + public string TypeName { get; set; } + /// /// 备注 /// diff --git a/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamValueOutput.cs b/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamValueOutput.cs index 24240d94..1a33b8cb 100644 --- a/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamValueOutput.cs +++ b/Myshipping.Core/Service/DjyTenantParam/Dto/DjyTenantParamValueOutput.cs @@ -7,4 +7,45 @@ public string ParaType { get; set; } public string ParaValue { get; set; } } + + /// + /// 列表输出 + /// + public class DjyTenantParamValueListOutput + { + /// + /// 参数类别 + /// + public string ParaCode { get; set; } + + /// + /// 类别名称 + /// + public string ParaName { get; set; } + /// + /// 租户id + /// + public long? TenantId { get; set; } + /// + /// 租户名称 + /// + public string TenantName { get; set; } + /// + /// 参数值 + /// + public string ItemCode { get; set; } + /// + /// 参数值名称 + /// + public string ItemCodeName { get; set; } + /// + /// 备注 + /// + public string Remark { get; set; } + /// + /// 排序 + /// + public int? Sort { get; set; } + + } } From 79468fd1fbebfe412c88cece68d41219aa72a5a2 Mon Sep 17 00:00:00 2001 From: jianghaiqing Date: Thu, 28 Mar 2024 23:33:22 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Myshipping.Application.csproj | 1 - .../Service/BookingSlot/BookingSlotService.cs | 74 +++ .../Dto/BookingSlotWithOrderDto.cs | 29 + .../BookingSlot/IBookingSlotService.cs | 16 + .../TaskManagePlat/Dtos/Draft/TaskDraftDto.cs | 41 ++ .../Dtos/Draft/TaskDraftShowDto.cs | 21 + .../Interface/ITaskManageBCService.cs | 8 + .../Interface/ITaskManageDRAFTService.cs | 14 +- .../TaskManagePlat/TaskManageBCService.cs | 187 +++++- .../TaskManagePlat/TaskManageDRAFTService.cs | 600 +++++++++++++++++- .../TaskManagePlat/TaskManageService.cs | 2 +- 11 files changed, 958 insertions(+), 35 deletions(-) create mode 100644 Myshipping.Application/Service/BookingSlot/Dto/BookingSlotWithOrderDto.cs create mode 100644 Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftDto.cs create mode 100644 Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftShowDto.cs diff --git a/Myshipping.Application/Myshipping.Application.csproj b/Myshipping.Application/Myshipping.Application.csproj index 352f920b..7d74091e 100644 --- a/Myshipping.Application/Myshipping.Application.csproj +++ b/Myshipping.Application/Myshipping.Application.csproj @@ -52,7 +52,6 @@ - diff --git a/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs b/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs index 26f8408b..aa36db82 100644 --- a/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs +++ b/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs @@ -1469,6 +1469,80 @@ namespace Myshipping.Application return id; } #endregion + + #region 检索舱位对应的订舱订单(BY 舱位主键) + /// + /// 检索舱位对应的订舱订单(BY 舱位主键) + /// + /// + /// 返回回执 + + public async Task SearchBookingSlotWithOrderById(long id) + { + BookingSlotWithOrderDto dto = null; + + var slotInfo = await _repBase.AsQueryable().FirstAsync(a => a.Id == id); + + if (slotInfo == null) + { + _logger.LogInformation($"id={id} 获取舱位失败,舱位不存在或已作废"); + + return dto; + } + + var list =_repAllocation.AsQueryable().Where(a => a.BOOKING_SLOT_ID == id).ToList(); + + dto = new BookingSlotWithOrderDto + { + BookingSlotId = slotInfo.Id, + }; + + if (list.Count > 0) + { + dto.HasBookingOrder = true; + dto.BookingOrderList = list.Select(x => x.Id).ToList(); + } + + return dto; + } + #endregion + + #region 检索舱位对应的订舱订单(BY 订舱编号) + /// + /// 检索舱位对应的订舱订单(BY 订舱编号) + /// + /// 订舱编号 + /// 返回回执 + + public async Task SearchBookingSlotWithOrderByNo(string slotBookingNo) + { + BookingSlotWithOrderDto dto = null; + + var slotInfo = await _repBase.AsQueryable().FirstAsync(a => a.SLOT_BOOKING_NO == slotBookingNo); + + if (slotInfo == null) + { + _logger.LogInformation($"slotBookingNo={slotBookingNo} 获取舱位失败,舱位不存在或已作废"); + + return dto; + } + + var list = _repAllocation.AsQueryable().Where(a => a.BOOKING_SLOT_ID == slotInfo.Id).ToList(); + + dto = new BookingSlotWithOrderDto + { + BookingSlotId = slotInfo.Id, + }; + + if (list.Count > 0) + { + dto.HasBookingOrder = true; + dto.BookingOrderList = list.Select(x => x.Id).ToList(); + } + + return dto; + } + #endregion } diff --git a/Myshipping.Application/Service/BookingSlot/Dto/BookingSlotWithOrderDto.cs b/Myshipping.Application/Service/BookingSlot/Dto/BookingSlotWithOrderDto.cs new file mode 100644 index 00000000..5d5f7b00 --- /dev/null +++ b/Myshipping.Application/Service/BookingSlot/Dto/BookingSlotWithOrderDto.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// + /// + public class BookingSlotWithOrderDto + { + /// + /// 舱位主键 + /// + public long BookingSlotId { get; set; } + + /// + /// 舱位对应的订舱主键组 + /// + public List BookingOrderList { get; set; } + + /// + /// 是否有对应的订舱订单 + /// + public bool HasBookingOrder { get; set; } = false; + } +} diff --git a/Myshipping.Application/Service/BookingSlot/IBookingSlotService.cs b/Myshipping.Application/Service/BookingSlot/IBookingSlotService.cs index 1f74733f..7ae52bb3 100644 --- a/Myshipping.Application/Service/BookingSlot/IBookingSlotService.cs +++ b/Myshipping.Application/Service/BookingSlot/IBookingSlotService.cs @@ -96,5 +96,21 @@ namespace Myshipping.Application /// 生成订舱订单请求 /// 返回回执 Task CreateBookingOrder(BookingGenerateDto model); + + /// + /// 检索舱位对应的订舱订单(BY 舱位主键) + /// + /// + /// 返回回执 + + Task SearchBookingSlotWithOrderById(long id); + + /// + /// 检索舱位对应的订舱订单(BY 订舱编号) + /// + /// 订舱编号 + /// 返回回执 + + Task SearchBookingSlotWithOrderByNo(string slotBookingNo); } } \ No newline at end of file diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftDto.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftDto.cs new file mode 100644 index 00000000..9c85a6af --- /dev/null +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftDto.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + public class TaskDraftDto + { + /// + /// 主键 + /// + public string PKId { get; set; } + + /// + /// 任务主键 + /// + public string TaskId { get; set; } + + /// + /// 主单号 + /// + public string MBlNo { get; set; } + + /// + /// 船公司 + /// + public string Carrier { get; set; } + + /// + /// 通知接收时间 + /// + public Nullable NoticeDate { get; set; } + + /// + /// 订舱ID + /// + public Nullable BookingId { get; set; } + } +} diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftShowDto.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftShowDto.cs new file mode 100644 index 00000000..a8e4eddb --- /dev/null +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/Draft/TaskDraftShowDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + public class TaskDraftShowDto: TaskDraftDto + { + /// + /// 是否已完成 + /// + public bool IsComplete { get; set; } + + /// + /// 完成时间 + /// + public Nullable CompleteTime { get; set; } + } +} diff --git a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageBCService.cs b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageBCService.cs index ea91d396..6cb87946 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageBCService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageBCService.cs @@ -96,5 +96,13 @@ namespace Myshipping.Application /// BC任务主键 /// 返回回执 Task SyncBookingSlotChange(string taskPKId); + + /// + /// 重新处理BC任务 + /// 对未匹配订舱订单的任务记录重新对应订舱订单 + /// + /// BC任务主键 + /// 返回回执 + Task SearchAndConnectBookingInfo(string taskPkId); } } diff --git a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageDRAFTService.cs b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageDRAFTService.cs index 6c34176c..d296340d 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageDRAFTService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageDRAFTService.cs @@ -14,14 +14,14 @@ namespace Myshipping.Application /// /// DRAFT主键 /// 返回回执 - Task GetInfo(string pkId); + Task GetInfo(string pkId); /// /// 通过任务主键获取DRAFT详情 /// /// DRAFT任务主键 /// 返回回执 - Task GetInfoByTaskId(string taskPkId); + Task GetInfoByTaskId(string taskPkId); /// /// 任务ID下载附件 @@ -29,7 +29,7 @@ namespace Myshipping.Application /// DRAFT任务主键 /// 附件分类代码 /// 返回数据流 - Task DownloadFile(string taskPKId, string fileCategory = "BC"); + Task DownloadFile(string taskPKId, string fileCategory = "DRAFT"); /// /// 发送邮件 @@ -37,5 +37,13 @@ namespace Myshipping.Application /// DRAFT任务主键 /// 返回回执 Task SendEmail(string taskPKId); + + /// + /// 重新处理DRAFT任务 + /// 对未匹配订舱订单的任务记录重新对应订舱订单 + /// + /// DRAFT任务主键 + /// + Task SearchAndConnectBookingInfo(string taskPkId); } } diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs index f42952c1..0e848afc 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs @@ -1,4 +1,5 @@ using Furion; +using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Furion.DynamicApiController; using Furion.FriendlyException; @@ -20,6 +21,7 @@ using Newtonsoft.Json; using Npoi.Mapper; using NPOI.HPSF; using NPOI.SS.Formula.Functions; +using NPOI.XWPF.UserModel; using Org.BouncyCastle.Asn1.Tsp; using RabbitMQ.Client; using SqlSugar; @@ -74,6 +76,8 @@ namespace Myshipping.Application private readonly IBookingValueAddedService _bookingValueAddedService; private readonly IDjyCustomerService _djyCustomerService; + private readonly INamedServiceProvider _namedBookingSlotServiceProvider; + const string CONST_BC_FILE_CODE = "bc"; const string CONST_BC_FILE_NAME = "Booking Confirmation"; @@ -93,6 +97,7 @@ namespace Myshipping.Application IBookingOrderService bookingOrderService, ILogger logger, IDjyCustomerService djyCustomerService, IBookingSlotService bookingSlotService, ISysCacheService cache, IBookingValueAddedService bookingValueAddedService, + INamedServiceProvider namedBookingSlotServiceProvider, SqlSugarRepository bookingSlotBaseRepository, SqlSugarRepository bookingSlotBaseCtnRepository, SqlSugarRepository bookingSlotAllocationRepository, @@ -1665,7 +1670,7 @@ namespace Myshipping.Application _logger.LogInformation($"推送邮件失败,异常:{ex.Message}"); result.succ = false; - result.msg = $"推送邮件失败,异常:{ex.Message}"; + result.msg = $"推送邮件失败,{ex.Message}"; } return result; @@ -1821,7 +1826,6 @@ namespace Myshipping.Application } #endregion - #region 通过邮件模板生成HTML /// /// 通过邮件模板生成HTML @@ -2194,6 +2198,185 @@ namespace Myshipping.Application return result; } #endregion + + #region 重试处理BC任务 + /// + /// 重试处理BC任务 + /// 对未匹配舱位、订舱订单的任务记录重新对应舱位、订舱订单 + /// + /// BC任务主键 + /// 返回回执 + [HttpGet("/TaskManageBC/SearchAndConnectBookingInfo")] + public async Task SearchAndConnectBookingInfo(string taskPkId) + { + /* + 只要解决BC变更、BC取消生成任务时未匹配到舱位、订舱订单,需要后边人工来点击匹配上舱位和订舱订单。 + 1、BC变更,重试匹配舱位,有舱位触发舱位的变更方法。 + 2、BC取消,重试匹配舱位,有舱位触发舱位的取消方法。 + */ + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId); + + if (taskBase == null) + throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息"); + + var taskBCInfo = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID); + + if (taskBCInfo == null) + throw Oops.Oh($"BC任务主键{taskPkId}无法获取业务信息"); + + if (taskBCInfo.BOOKING_SLOT_ID.HasValue) + throw Oops.Oh($"当前BC任务已有匹配的舱位"); + + string mblNo = taskBCInfo.MBL_NO.ToUpper().Trim(); + + var server = _namedBookingSlotServiceProvider.GetService(nameof(BookingSlotService)); + var slotInfo = await server.SearchBookingSlotWithOrderByNo(mblNo); + + if (slotInfo == null) + throw Oops.Oh($"提单号{mblNo}未提取有效的舱位信息"); + + taskBCInfo.BOOKING_SLOT_ID = slotInfo.BookingSlotId; + taskBCInfo.UpdatedUserId = UserManager.UserId; + taskBCInfo.UpdatedUserName = UserManager.Name; + + //更新任务BC + await _taskBCInfoRepository.AsUpdateable(taskBCInfo).UpdateColumns(it => new + { + it.BOOKING_SLOT_ID, + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName + + }).ExecuteCommandAsync(); + + _logger.LogInformation($"提单号{mblNo} 提取到舱位ID,更新完成"); + + //取消舱位 + if (taskBCInfo.BUSI_TYPE == TaskBusiTypeEnum.CANCELLATION.ToString()) + { + BookingSlotBaseApiDto slotModel = new BookingSlotBaseApiDto + { + DataObj = new BookingSlotBaseApiSaveDto + { + CARRIERID = taskBCInfo.CARRIERID, + SLOT_BOOKING_NO = taskBCInfo.MBL_NO, + CtnList = new List() + }, + OpType = "cancellation" + }; + + _logger.LogInformation($"提单号{mblNo} 推送舱位取消"); + + var pushRlt = await server.ApiReceive(JSON.Serialize(slotModel)); + + _logger.LogInformation($"提单号{mblNo} 推送舱位取消,结果={JSON.Serialize(pushRlt)}"); + } + else if (taskBCInfo.BUSI_TYPE == TaskBusiTypeEnum.BC_MODIFY.ToString()) + { + BookingSlotBaseApiDto slotModel = new BookingSlotBaseApiDto + { + DataObj = new BookingSlotBaseApiSaveDto + { + CARRIERID = taskBCInfo.CARRIERID, + SLOT_BOOKING_NO = taskBCInfo.MBL_NO, + BOOKING_PARTY = taskBCInfo.BOOKING_PARTY, + BOOKING_SLOT_TYPE = taskBCInfo.BOOKING_SLOT_TYPE, + BOOKING_SLOT_TYPE_NAME = taskBCInfo.BOOKING_SLOT_TYPE_NAME, + VESSEL = taskBCInfo.VESSEL, + VOYNO = taskBCInfo.VOYNO, + VGM_SUBMISSION_CUT_DATE = taskBCInfo.VGM_CUTOFF_TIME, + WEEK_AT = taskBCInfo.WEEK_AT, + CARRIAGE_TYPE = taskBCInfo.CARRIAGE_TYPE, + CARRIAGE_TYPE_NAME = taskBCInfo.CARRIAGE_TYPE_NAME, + CONTRACT_NO = taskBCInfo.CONTRACTNO, + CTN_STAT = taskBCInfo.CTN_STAT, + CY_CUT_DATE = taskBCInfo.CY_CUTOFF_TIME, + DETENSION_FREE_DAYS = taskBCInfo.DETENSION_FREE_DAYS, + ETD = taskBCInfo.ETD, + ETA = taskBCInfo.ETA, + LANECODE = taskBCInfo.LANECODE, + LANENAME = taskBCInfo.LANENAME, + MANIFEST_CUT_DATE = taskBCInfo.MANIFEST_CUT_DATE, + MDGF_CUT_DATE = taskBCInfo.MDGF_CUT_DATE, + PLACEDELIVERY = taskBCInfo.PLACEDELIVERY, + PLACERECEIPT = taskBCInfo.PLACERECEIPT, + PORTDISCHARGE = taskBCInfo.PORTDISCHARGE, + PORTLOAD = taskBCInfo.PORTLOAD, + SI_CUT_DATE = taskBCInfo.SI_CUT_DATE, + TRANSFER_PORT_1 = taskBCInfo.TRANSFER_PORT_1, + TRANSFER_PORT_2 = taskBCInfo.TRANSFER_PORT_2, + CtnList = new List() + }, + OpType = "add" + }; + + var ctnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == taskBCInfo.PK_ID).ToList(); + + if (ctnList.Count > 0) + { + ctnList.ForEach(t => + { + BookingSlotCtnSaveInput ctn = new BookingSlotCtnSaveInput + { + CTNALL = t.CTNALL, + CTNNUM = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1 + }; + + slotModel.DataObj.CtnList.Add(ctn); + }); + } + + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + + var taskFileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == taskBCInfo.TASK_ID).ToList(); + + DynameFileInfo dynameFile = null; + DynameFileInfo dynameNoticeFile = null; + + if (taskFileList.Any(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString())) + { + var fileInfo = taskFileList.FirstOrDefault(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString()); + var fileFullPath = Path.Combine(dirAbs, fileInfo.FILE_PATH); + + dynameFile = new DynameFileInfo + { + FileBytes = File.ReadAllBytes(fileFullPath), + FileName = Path.GetFileName(fileFullPath) + }; + } + + if (taskFileList.Any(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC_NOTICE.ToString())) + { + var fileInfo = taskFileList.FirstOrDefault(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString()); + var fileFullPath = Path.Combine(dirAbs, fileInfo.FILE_PATH); + + dynameNoticeFile = new DynameFileInfo + { + FileBytes = File.ReadAllBytes(fileFullPath), + FileName = Path.GetFileName(fileFullPath) + }; + } + + _logger.LogInformation($"提单号{mblNo} 推送舱位更新"); + + var pushRlt = await server.InnerApiReceive(slotModel, dynameFile, dynameNoticeFile); + + _logger.LogInformation($"提单号{mblNo} 推送舱位更新,结果={JSON.Serialize(pushRlt)}"); + } + + result.succ = true; + result.msg = "成功"; + + return result; + } + #endregion } /// diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs index 06dbcb5b..389e18c9 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs @@ -1,15 +1,26 @@ -using Furion.DynamicApiController; +using Furion; +using Furion.DynamicApiController; using Furion.FriendlyException; +using Furion.JsonSerialization; +using Furion.RemoteRequest.Extensions; +using HtmlAgilityPack; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Myshipping.Application.ConfigOption; using Myshipping.Application.Entity; using Myshipping.Core; +using Myshipping.Core.Entity; using Myshipping.Core.Service; +using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Net.Http; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Web; namespace Myshipping.Application { @@ -22,10 +33,34 @@ namespace Myshipping.Application private readonly ISysCacheService _cache; private readonly ILogger _logger; private readonly SqlSugarRepository _taskBaseRepository; + private readonly SqlSugarRepository _taskFileRepository; + private readonly SqlSugarRepository _taskDraftInfoRepository; + private readonly SqlSugarRepository _djyUserMailAccount; + private readonly SqlSugarRepository _bookingOrderContactRepository; + private readonly SqlSugarRepository _bookingOrderRepository; + private readonly SqlSugarRepository _sysUserRepository; + private readonly IDjyCustomerService _djyCustomerService; - public TaskManageDRAFTService(SqlSugarRepository taskBCInfoRepository, + public TaskManageDRAFTService(SqlSugarRepository taskBaseRepository, + SqlSugarRepository taskFileRepository, + SqlSugarRepository taskDraftInfoRepository, + SqlSugarRepository djyUserMailAccount, + SqlSugarRepository bookingOrderContactRepository, + SqlSugarRepository bookingOrderRepository, + SqlSugarRepository sysUserRepository, + IDjyCustomerService djyCustomerService, ILogger logger) { + _taskBaseRepository = taskBaseRepository; + _taskFileRepository = taskFileRepository; + _taskDraftInfoRepository = taskDraftInfoRepository; + _bookingOrderRepository = bookingOrderRepository; + _bookingOrderContactRepository = bookingOrderContactRepository; + _djyUserMailAccount = djyUserMailAccount; + + _djyCustomerService = djyCustomerService; + _sysUserRepository = sysUserRepository; + _logger = logger; } @@ -35,38 +70,39 @@ namespace Myshipping.Application /// /// DRAFT主键 /// 返回回执 - public async Task GetInfo(string pkId) + [HttpGet("/TaskManageDRAFT/GetInfo")] + public async Task GetInfo(string pkId) { - TaskManageOrderResultDto result = new TaskManageOrderResultDto(); - - try - { - //var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == pkId); - - //if (bcOrder == null) - // throw Oops.Oh($"BC主键{pkId}无法获取业务信息"); + TaskDraftShowDto dto = new TaskDraftShowDto(); - //var BCCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == pkId).ToList(); + var draft = _taskDraftInfoRepository.AsQueryable().First(a => a.PK_ID == pkId); - //TaskBCShowBaseDto model = bcOrder.Adapt(); + if (draft == null) + throw Oops.Oh($"DRAFT主键{pkId}无法获取业务信息"); - //if (BCCtnList.Count > 0) - // model.CtnList = BCCtnList.Adapt>(); + var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == draft.TASK_ID); - //var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToList(); + if (taskBase == null) + throw Oops.Oh($"任务主键无法获取业务信息"); - //if (fileList.Count > 0) - // model.FileList = fileList.Adapt>(); + dto = new TaskDraftShowDto + { + PKId = draft.PK_ID, + TaskId = draft.TASK_ID, + Carrier = draft.CARRIER, + BookingId = draft.BOOKING_ID, + MBlNo = draft.MBL_NO, + NoticeDate = draft.NOTICE_DATE, + }; - } - catch (Exception ex) + if (dto != null) { - result.succ = false; - result.msg = $"获取BC详情异常,原因:{ex.Message}"; + dto.IsComplete = taskBase.IS_COMPLETE == 1 ? true : false; + dto.CompleteTime = taskBase.COMPLETE_DATE; } - return result; + return dto; } #endregion @@ -76,9 +112,38 @@ namespace Myshipping.Application /// /// DRAFT任务主键 /// 返回回执 - public async Task GetInfoByTaskId(string taskPkId) + [HttpGet("/TaskManageDRAFT/GetInfoByTaskId")] + public async Task GetInfoByTaskId(string taskPkId) { - return null; + TaskDraftShowDto dto = new TaskDraftShowDto(); + + var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId); + + if (taskBase == null) + throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息"); + + var draft = _taskDraftInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID); + + if (draft == null) + throw Oops.Oh($"DRAFT主键{taskPkId}无法获取业务信息"); + + dto = new TaskDraftShowDto + { + PKId = draft.PK_ID, + TaskId = draft.TASK_ID, + Carrier = draft.CARRIER, + BookingId = draft.BOOKING_ID, + MBlNo = draft.MBL_NO, + NoticeDate = draft.NOTICE_DATE, + }; + + if (dto != null) + { + dto.IsComplete = taskBase.IS_COMPLETE == 1 ? true : false; + dto.CompleteTime = taskBase.COMPLETE_DATE; + } + + return dto; } #endregion @@ -89,9 +154,49 @@ namespace Myshipping.Application /// DRAFT任务主键 /// 附件分类代码 /// 返回数据流 - public Task DownloadFile(string taskPKId, string fileCategory = "DRAFT") + [HttpGet("/TaskManageDRAFT/DownloadFile")] + public async Task DownloadFile([FromQuery] string taskPKId, [FromQuery] string fileCategory = "DRAFT") { - return null; + var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId); + if (bcTaskInfo == null) + { + throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息"); + } + + TaskFileCategoryEnum fileCategoryEnum = TaskFileCategoryEnum.NONE; + + System.Enum.TryParse(fileCategory, out fileCategoryEnum); + + if (fileCategoryEnum == TaskFileCategoryEnum.NONE) + { + throw Oops.Oh($"附件分类代码错误,请提供正确的分类代码"); + } + + string name = fileCategoryEnum.ToString(); + + var fileInfo = await _taskFileRepository.AsQueryable().FirstAsync(u => u.TASK_PKID == taskPKId && u.FILE_CATEGORY == name); + + if (fileInfo == null) + { + throw Oops.Oh($"任务主键{taskPKId}没有可下载的附件"); + } + + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + + var fileFullPath = Path.Combine(dirAbs, fileInfo.FILE_PATH); + if (!File.Exists(fileFullPath)) + { + throw Oops.Oh($"任务主键{taskPKId} 附件下载请求失败,请确认文件是否存在"); + } + + var fileName = HttpUtility.UrlEncode(fileInfo.FILE_NAME, Encoding.GetEncoding("UTF-8")); + var result = new FileStreamResult(new FileStream(fileFullPath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; + return result; } #endregion @@ -101,9 +206,448 @@ namespace Myshipping.Application /// /// DRAFT任务主键 /// 返回回执 + [HttpGet("/TaskManageDRAFT/SendEmail")] public async Task SendEmail(string taskPKId) { - return null; + if (string.IsNullOrWhiteSpace(taskPKId)) + throw Oops.Oh($"DRAFT任务主键不能为空"); + + var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId); + if (bcTaskInfo == null) + { + throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息"); + } + + var draft = _taskDraftInfoRepository.AsQueryable().First(a => a.TASK_ID == bcTaskInfo.PK_ID); + + if (draft == null) + throw Oops.Oh($"任务主键{taskPKId}无法获取DRAFT业务信息"); + + return await GenerateSendEmail(draft); + } + #endregion + + #region 生成并推送邮件 + /// + /// 生成并推送邮件 + /// + /// DRAFT任务详情 + /// 返回回执 + private async Task GenerateSendEmail(TaskDraftInfo taskDraftInfo) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + try + { + /* + 1、提取邮件接收人、通过订舱的委托客户获取联系人信息(提取联系人中备注是BCNotice的邮箱) + 2、提取当票订舱对应的操作人邮箱、通过订舱的委托客户获取操作OP的邮箱 + 3、读取用户邮箱配置,主要提取显示名称BCNotice的邮箱,用来作为公共邮箱来发送邮件。 + 4、读取邮件模板,填充详情。 + 5、推送邮件给邮件接收人 + */ + + //读取订舱数据 + var bookingOrderEntity = _bookingOrderRepository.AsQueryable() + .First(a => a.Id == taskDraftInfo.BOOKING_ID); + + + if (bookingOrderEntity == null) + { + throw Oops.Oh($"订舱详情获取失败,请确认订舱是否存在或已删除"); + } + + _logger.LogInformation($"获取订舱详情完成,bookid={bookingOrderEntity.Id}"); + + if (!bookingOrderEntity.CUSTOMERID.HasValue || (bookingOrderEntity.CUSTOMERID.HasValue && bookingOrderEntity.CUSTOMERID.Value == 0)) + { + throw Oops.Oh($"订舱的委托客户不能为空"); + } + + var djyCustomerInfo = _djyCustomerService.Detail(new GetDjyCustomerInput { Id = bookingOrderEntity.CUSTOMERID.Value }) + .GetAwaiter().GetResult(); + + if (djyCustomerInfo == null) + { + throw Oops.Oh($"委托单位详情获取失败,请确认委托单位是否存在或已删除"); + } + + _logger.LogInformation($"获取委托单位详情完成,djyCustomerId={djyCustomerInfo.Id}"); + + //DjyCustomerContactOutput djyCustomerContactMan = null; + + //TO 邮件接收人 + string toEmail = string.Empty; + //订舱OP的邮箱 + string opEmail = string.Empty; + + var bookingContactList = _bookingOrderContactRepository.AsQueryable() + .Where(a => a.BookingId == taskDraftInfo.BOOKING_ID).ToList(); + + if (bookingContactList == null || bookingContactList.Count == 0) + { + _logger.LogInformation($"当前订舱未指定的联系人,toEmail={toEmail}"); + } + + toEmail = string.Join(";", bookingContactList.Select(x => x.Email.Trim()).Distinct().ToArray()); + + //获取操作OP的邮箱 + if (!string.IsNullOrWhiteSpace(bookingOrderEntity.OPID)) + { + var opId = long.Parse(bookingOrderEntity.OPID); + var opUser = _sysUserRepository.AsQueryable().First(a => a.Id == opId); + + if (opUser != null && !string.IsNullOrWhiteSpace(opUser.Email)) + { + opEmail = opUser.Email.Trim(); + + _logger.LogInformation($"获取操作OP的邮箱,opEmail={opEmail} id={opId} name={opUser.Name}"); + } + } + + //提取当前公共邮箱的配置 + var publicMailAccount = _djyUserMailAccount.FirstOrDefault(x => x.CreatedUserId == UserManager.UserId + && x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != ""); + + if (publicMailAccount == null) + { + throw Oops.Oh($"提取公共邮箱配置失败,请在用户邮箱账号管理增加配置显示名为BCNotice"); + } + + _logger.LogInformation($"提取当前公共邮箱的配置完成,id={publicMailAccount.Id}"); + + string emailTitle = $"Draft : {taskDraftInfo.MBL_NO}"; + + string filePath = string.Empty; + + SysUser opUserInfo = null; + + if (!string.IsNullOrWhiteSpace(bookingOrderEntity.OPID) && Regex.IsMatch(bookingOrderEntity.OPID, "[0-9]+")) + opUserInfo = _sysUserRepository.AsQueryable().First(u => u.Id == long.Parse(bookingOrderEntity.OPID)); + + + //读取邮件模板并填充数据 + string emailHtml = GenerateSendEmailHtml(taskDraftInfo, opUserInfo, UserManager.TENANT_NAME).GetAwaiter().GetResult(); + + _logger.LogInformation($"生成邮件BODY,结果:{emailHtml}"); + + var fileInfo = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == taskDraftInfo.TASK_ID && a.FILE_CATEGORY.Contains("draft_notice")) + .OrderByDescending(a => a.CreatedTime).First(); + + if (fileInfo == null) + { + throw Oops.Oh($"提取DRAFT的文件失败,不能发送邮件"); + } + + _logger.LogInformation($"获取订舱附件地址,结果:{fileInfo.FILE_PATH}"); + + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + + filePath = Path.Combine(dirAbs, fileInfo.FILE_PATH); + + 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() + }; + + _logger.LogInformation($"生成请求邮件参数,结果:{JSON.Serialize(emailApiUserDefinedDto)}"); + + + //推送邮件 + var emailRlt = await PushEmail(emailApiUserDefinedDto, filePath); + + _logger.LogInformation($"推送邮件完成,结果:{JSON.Serialize(emailRlt)}"); + + result.succ = true; + result.msg = "成功"; + } + catch (Exception ex) + { + _logger.LogInformation($"推送邮件失败,异常:{ex.Message}"); + + result.succ = false; + result.msg = $"推送邮件失败,{ex.Message}"; + } + + return result; + } + #endregion + + #region 通过邮件模板生成HTML + /// + /// 通过邮件模板生成HTML + /// + /// BC任务详情 + /// 订舱OP详情 + /// 当前租户全称 + /// 返回生成的HTML + private async Task GenerateSendEmailHtml(TaskDraftInfo taskDraftInfo, SysUser opUserInfo, string tenantName) + { + string result = string.Empty; + + /* + 1、加载模板文件,读取HTML + 2、读取main、conta的tr行,替换业务数据 + 3、返回HTML的文本信息。 + */ + try + { + string templatePath = App.Configuration["EmailTemplateFilePath"]; + + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + templatePath = $"{dirAbs}{templatePath}\\DraftEmailTemplate.html"; + + string baseHtml = File.ReadAllText(templatePath); + + if (string.IsNullOrWhiteSpace(baseHtml)) + throw Oops.Oh($"读取邮件模板失败"); + + 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.Tel)) + { + baseHtml = baseHtml.Replace("#optel#", opUserInfo.Tel); + } + else + { + baseHtml = baseHtml.Replace("#optel#", ""); + } + + HtmlDocument html = new HtmlDocument(); + html.LoadHtml(baseHtml); + + HtmlNode baseTable = html.DocumentNode.SelectNodes("//table[@class='base-table']").FirstOrDefault(); + + if (baseTable == null) + throw Oops.Oh($"读取邮件模板格式错误,定位base-table失败"); + + + var baseTrList = baseTable.SelectNodes(".//tr"); + + foreach (var baseTr in baseTrList) + { + var tdList = baseTr.SelectNodes(".//td"); + + foreach (var baseTd in tdList) + { + if (baseTd.Attributes["class"].Value == "billno-val") + { + baseTd.InnerHtml = taskDraftInfo.MBL_NO; + } + else if (baseTd.Attributes["class"].Value == "carrier-val") + { + baseTd.InnerHtml = taskDraftInfo.CARRIER; + } + } + } + + var noreplyTr = html.DocumentNode.SelectNodes("//tr[@class='email-noreply']").FirstOrDefault(); + + if (noreplyTr != null) + { + var currTd = noreplyTr.SelectNodes(".//td").FirstOrDefault(); + + if (currTd != null) + { + var currPList = currTd.SelectNodes(".//p"); + + foreach (var baseP in currPList) + { + if (baseP.Attributes["class"].Value == "notice-comp-val") + { + baseP.InnerHtml = tenantName; + } + } + } + + } + + result = html.DocumentNode.OuterHtml; + } + catch (Exception ex) + { + _logger.LogInformation($"通过邮件模板生成HTML异常,原因={ex.Message}"); + + throw ex; + } + + return result; + } + #endregion + + #region 推送邮件 + /// + /// 推送邮件 + /// + /// 自定义邮件详情 + /// 文件路径 + /// 返回回执 + private async Task PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto, string filePath) + { + CommonWebApiResult result = new CommonWebApiResult { succ = true }; + + List emailList = new List(); + + 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); + + emailApiUserDefinedDto.Attaches.Add(new AttachesInfo + { + AttachName = Path.GetFileName(filePath), + 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.,{strJoin}"); + + _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 重新处理DRAFT任务 + /// + /// 重新处理DRAFT任务 + /// 对未匹配订舱订单的任务记录重新对应订舱订单 + /// + /// DRAFT任务主键 + /// + [HttpGet("/TaskManageDRAFT/SearchAndConnectBookingInfo")] + public async Task 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 draft = _taskDraftInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID); + + if (draft == null) + throw Oops.Oh($"DRAFT主键{taskPkId}无法获取业务信息"); + + if (draft.BOOKING_ID.HasValue) + throw Oops.Oh($"当前DRAFT已有匹配的订舱订单"); + + string mblNo = draft.MBL_NO.ToUpper().Trim(); + + var bookingInfo = _bookingOrderRepository.AsQueryable().Filter(null, true) + .FirstAsync(a => a.MBLNO == mblNo && a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0)); + + if (bookingInfo == null) + throw Oops.Oh($"提单号{mblNo}未提取有效的订舱订单"); + + draft.BOOKING_ID = bookingInfo.Id; + draft.UpdatedUserId = UserManager.UserId; + draft.UpdatedUserName = UserManager.Name; + + //更新任务 + await _taskDraftInfoRepository.AsUpdateable(draft).UpdateColumns(it => new + { + it.BOOKING_ID, + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName + + }).ExecuteCommandAsync(); + + result.succ = true; + result.msg = "成功"; + + return result; } #endregion } diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs index d18abe85..f1d0c698 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs @@ -476,7 +476,7 @@ namespace Myshipping.Application { attachFileType = "draftnoticefiles"; - fileCategory = TaskFileCategoryEnum.DRAFT.ToString(); + fileCategory = TaskFileCategoryEnum.DRAFT_NOTICE.ToString(); } var noExtensionFileName = Path.GetFileNameWithoutExtension(modifyFile.FileName); From aed2650ccb396cff33b32ebb73f8be13eb146088 Mon Sep 17 00:00:00 2001 From: jianghaiqing Date: Thu, 28 Mar 2024 23:52:34 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TaskManagePlat/TaskManageDRAFTService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs index 389e18c9..c13bcef6 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs @@ -49,6 +49,7 @@ namespace Myshipping.Application SqlSugarRepository bookingOrderRepository, SqlSugarRepository sysUserRepository, IDjyCustomerService djyCustomerService, + ISysCacheService cache, ILogger logger) { _taskBaseRepository = taskBaseRepository; @@ -62,6 +63,7 @@ namespace Myshipping.Application _sysUserRepository = sysUserRepository; _logger = logger; + _cache = cache; } #region 获取DRAFT详情 @@ -625,7 +627,7 @@ namespace Myshipping.Application string mblNo = draft.MBL_NO.ToUpper().Trim(); var bookingInfo = _bookingOrderRepository.AsQueryable().Filter(null, true) - .FirstAsync(a => a.MBLNO == mblNo && a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0)); + .First(a => a.MBLNO == mblNo && a.IsDeleted == false && (a.ParentId == null || a.ParentId == 0)); if (bookingInfo == null) throw Oops.Oh($"提单号{mblNo}未提取有效的订舱订单"); From aa5f2015b3c8a302b0e4c303a3748cae46f11a18 Mon Sep 17 00:00:00 2001 From: jianghaiqing Date: Fri, 29 Mar 2024 08:16:44 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EmailTemplate/DraftEmailTemplate.html | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Myshipping.Web.Entry/wwwroot/EmailTemplate/DraftEmailTemplate.html diff --git a/Myshipping.Web.Entry/wwwroot/EmailTemplate/DraftEmailTemplate.html b/Myshipping.Web.Entry/wwwroot/EmailTemplate/DraftEmailTemplate.html new file mode 100644 index 00000000..1ea1edb8 --- /dev/null +++ b/Myshipping.Web.Entry/wwwroot/EmailTemplate/DraftEmailTemplate.html @@ -0,0 +1,50 @@ + + + + + + + + 邮件模板 + + + + + + + + + +
+ + + + + + + + + + +
+

Dear Customer,

+
+ + + + + + + + + +
提单号:TEST123456
船公司:TEST123456
+
+
+ + From ec1251e4d3b690cdf947a7fa76a35d6669ddc5f8 Mon Sep 17 00:00:00 2001 From: jianghaiqing Date: Fri, 29 Mar 2024 08:53:55 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=8F=B0=E7=AB=99DRAFT=E9=82=AE=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TaskManagePlat/TaskManageBCService.cs | 12 ++++++++++-- .../Service/TaskManagePlat/TaskManageDRAFTService.cs | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs index 0e848afc..3379f1d1 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageBCService.cs @@ -1729,7 +1729,11 @@ namespace Myshipping.Application baseHtml = baseHtml.Replace("#opemail#", ""); } - if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Tel)) + 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); } @@ -1878,7 +1882,11 @@ namespace Myshipping.Application baseHtml = baseHtml.Replace("#opemail#", ""); } - if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Tel)) + 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); } diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs index c13bcef6..ceb4d39f 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageDRAFTService.cs @@ -441,7 +441,11 @@ namespace Myshipping.Application baseHtml = baseHtml.Replace("#opemail#", ""); } - if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Tel)) + 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); }