|
|
|
|
using Furion;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DistributedIDGenerator;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
using Furion.JsonSerialization;
|
|
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
|
|
using HtmlAgilityPack;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Myshipping.Application.ConfigOption;
|
|
|
|
|
using Myshipping.Application.Entity;
|
|
|
|
|
using Myshipping.Application.Enum;
|
|
|
|
|
using Myshipping.Application.Service.BookingOrder;
|
|
|
|
|
using Myshipping.Application.Service.BookingSlot.Dto;
|
|
|
|
|
using Myshipping.Core;
|
|
|
|
|
using Myshipping.Core.Entity;
|
|
|
|
|
using Myshipping.Core.Service;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Npoi.Mapper;
|
|
|
|
|
using NPOI.HPSF;
|
|
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
|
|
using NPOI.Util;
|
|
|
|
|
using NPOI.XWPF.UserModel;
|
|
|
|
|
using Org.BouncyCastle.Asn1.Tsp;
|
|
|
|
|
using RabbitMQ.Client;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
using System.Net.Http.Headers;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
using System.Security.Principal;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Web;
|
|
|
|
|
using System.Xml;
|
|
|
|
|
using Yitter.IdGenerator;
|
|
|
|
|
|
|
|
|
|
namespace Myshipping.Application
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// BC任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
[ApiDescriptionSettings("Application", Name = "TaskManageBC", Order = 10)]
|
|
|
|
|
public class TaskManageBCService: ITaskManageBCService, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
private readonly ISysCacheService _cache;
|
|
|
|
|
private readonly ILogger<TaskManageBCService> _logger;
|
|
|
|
|
|
|
|
|
|
private readonly SqlSugarRepository<TaskBCInfo> _taskBCInfoRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskBCCTNInfo> _taskBCCTNInfoRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskFileInfo> _taskFileRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingCtn> _bookingCtnRepository;
|
|
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingFile> _bookingFileRepository;
|
|
|
|
|
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccount;
|
|
|
|
|
private readonly SqlSugarRepository<BookingOrderContact> _bookingOrderContactRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingSlotCompare> _bookingSlotCompareRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingSlotBase> _bookingSlotBaseRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingSlotCtn> _bookingSlotBaseCtnRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingSlotAllocation> _bookingSlotAllocationRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingSlotAllocationCtn> _bookingSlotAllocationCtnRepository;
|
|
|
|
|
private readonly SqlSugarRepository<BookingDeliveryRecord> _bookingDeliveryRecordRep;
|
|
|
|
|
private readonly SqlSugarRepository<BookingDeliveryRecordCtn> _bookingDeliveryRecordCtnRep;
|
|
|
|
|
|
|
|
|
|
private readonly IServiceWorkFlowBaseService _serviceWorkFlowBaseService;
|
|
|
|
|
private readonly IBookingOrderService _bookingOrderService;
|
|
|
|
|
private readonly IBookingSlotService _bookingSlotService;
|
|
|
|
|
private readonly IBookingValueAddedService _bookingValueAddedService;
|
|
|
|
|
private readonly IDjyCustomerService _djyCustomerService;
|
|
|
|
|
private readonly INamedServiceProvider<IBookingMSKAPIService> _namedBookingMSKAPIServiceProvider;
|
|
|
|
|
private readonly IDjyTenantParamService _djyTenantParamService;
|
|
|
|
|
|
|
|
|
|
private readonly INamedServiceProvider<IBookingSlotService> _namedBookingSlotServiceProvider;
|
|
|
|
|
|
|
|
|
|
const string CONST_BC_FILE_CODE = "bc";
|
|
|
|
|
const string CONST_BC_FILE_NAME = "Booking Confirmation";
|
|
|
|
|
|
|
|
|
|
const string CONST_BC_NOTICE_FILE_CODE = "bc_notice";
|
|
|
|
|
const string CONST_BC_NOTICE_FILE_NAME = "Booking Confirmation Notice";
|
|
|
|
|
|
|
|
|
|
//租户BC默认转发KEY
|
|
|
|
|
const string CONST_BC_DEFAULT_PARAM = "BC_TASK_AUTO_TRANSMIT";
|
|
|
|
|
//租户AMENDMENT默认转发KEY
|
|
|
|
|
const string CONST_AMENDMENT_DEFAULT_PARAM = "AMENDMENT_TASK_AUTO_TRANSMIT";
|
|
|
|
|
//租户CANCELLATION默认转发KEY
|
|
|
|
|
const string CONST_CANCELLATION_DEFAULT_PARAM = "CANCELLATION_TASK_AUTO_TRANSMIT";
|
|
|
|
|
//租户AMENDMENT默认钉钉消息KEY
|
|
|
|
|
const string CONST_AMENDMENT_DING_DEFAULT_PARAM = "AMENDMENT_TASK_DING_NOTICE";
|
|
|
|
|
//租户CANCELLATION默认钉钉消息KEY
|
|
|
|
|
const string CONST_CANCELLATION_DING_DEFAULT_PARAM = "CANCELLATION_TASK_DING_NOTICE";
|
|
|
|
|
|
|
|
|
|
public TaskManageBCService(SqlSugarRepository<TaskBCInfo> taskBCInfoRepository,
|
|
|
|
|
SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
|
|
|
|
|
SqlSugarRepository<TaskBCCTNInfo> taskBCCTNInfoRepository,
|
|
|
|
|
SqlSugarRepository<TaskFileInfo> taskFileRepository,
|
|
|
|
|
SqlSugarRepository<BookingOrder> bookingOrderRepository,
|
|
|
|
|
SqlSugarRepository<BookingCtn> bookingCtnRepository,
|
|
|
|
|
SqlSugarRepository<SysUser> sysUserRepository,
|
|
|
|
|
SqlSugarRepository<BookingFile> bookingFileRepository,
|
|
|
|
|
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount,
|
|
|
|
|
IServiceWorkFlowBaseService serviceWorkFlowBaseService,
|
|
|
|
|
IBookingOrderService bookingOrderService, ILogger<TaskManageBCService> logger,
|
|
|
|
|
IDjyCustomerService djyCustomerService,
|
|
|
|
|
IBookingSlotService bookingSlotService, ISysCacheService cache, IBookingValueAddedService bookingValueAddedService,
|
|
|
|
|
INamedServiceProvider<IBookingSlotService> namedBookingSlotServiceProvider,
|
|
|
|
|
INamedServiceProvider<IBookingMSKAPIService> namedBookingMSKAPIServiceProvider,
|
|
|
|
|
IDjyTenantParamService djyTenantParamService,
|
|
|
|
|
SqlSugarRepository<BookingSlotBase> bookingSlotBaseRepository,
|
|
|
|
|
SqlSugarRepository<BookingSlotCtn> bookingSlotBaseCtnRepository,
|
|
|
|
|
SqlSugarRepository<BookingSlotAllocation> bookingSlotAllocationRepository,
|
|
|
|
|
SqlSugarRepository<BookingSlotAllocationCtn> bookingSlotAllocationCtnRepository,
|
|
|
|
|
SqlSugarRepository<BookingOrderContact> bookingOrderContactRepository,
|
|
|
|
|
SqlSugarRepository<BookingSlotCompare> bookingSlotCompareRepository)
|
|
|
|
|
{
|
|
|
|
|
_taskBaseRepository = taskBaseRepository;
|
|
|
|
|
_taskBCInfoRepository = taskBCInfoRepository;
|
|
|
|
|
_taskBCCTNInfoRepository = taskBCCTNInfoRepository;
|
|
|
|
|
_taskFileRepository = taskFileRepository;
|
|
|
|
|
_bookingOrderRepository = bookingOrderRepository;
|
|
|
|
|
_bookingCtnRepository = bookingCtnRepository;
|
|
|
|
|
_sysUserRepository = sysUserRepository;
|
|
|
|
|
_serviceWorkFlowBaseService = serviceWorkFlowBaseService;
|
|
|
|
|
_bookingOrderService = bookingOrderService;
|
|
|
|
|
_bookingSlotService = bookingSlotService;
|
|
|
|
|
_cache = cache;
|
|
|
|
|
_bookingValueAddedService = bookingValueAddedService;
|
|
|
|
|
_bookingFileRepository = bookingFileRepository;
|
|
|
|
|
_djyCustomerService = djyCustomerService;
|
|
|
|
|
_djyUserMailAccount = djyUserMailAccount;
|
|
|
|
|
_bookingOrderContactRepository = bookingOrderContactRepository;
|
|
|
|
|
_bookingSlotCompareRepository = bookingSlotCompareRepository;
|
|
|
|
|
|
|
|
|
|
_bookingSlotBaseRepository = bookingSlotBaseRepository;
|
|
|
|
|
_bookingSlotBaseCtnRepository = bookingSlotBaseCtnRepository;
|
|
|
|
|
_bookingSlotAllocationRepository = bookingSlotAllocationRepository;
|
|
|
|
|
_bookingSlotAllocationCtnRepository = bookingSlotAllocationCtnRepository;
|
|
|
|
|
_namedBookingMSKAPIServiceProvider = namedBookingMSKAPIServiceProvider;
|
|
|
|
|
_namedBookingSlotServiceProvider = namedBookingSlotServiceProvider;
|
|
|
|
|
_djyTenantParamService = djyTenantParamService;
|
|
|
|
|
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 获取BC详情
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取BC详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pkId">BC主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/GetInfo")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> 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}无法获取业务信息");
|
|
|
|
|
|
|
|
|
|
var BCCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == pkId).ToList();
|
|
|
|
|
|
|
|
|
|
TaskBCShowBaseDto model = bcOrder.Adapt<TaskBCShowBaseDto>();
|
|
|
|
|
|
|
|
|
|
if (BCCtnList.Count > 0)
|
|
|
|
|
model.CtnList = BCCtnList.Adapt<List<TaskBCCTNInfoDto>>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToList();
|
|
|
|
|
|
|
|
|
|
if (fileList.Count > 0)
|
|
|
|
|
model.FileList = fileList.Adapt<List<TaskFileDto>>();
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.ext = model;
|
|
|
|
|
|
|
|
|
|
//如果当前BC有对应记录,则读取订舱详情
|
|
|
|
|
if (bcOrder.BOOKING_ORDER_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var bkOrder = await _bookingOrderRepository.AsQueryable().
|
|
|
|
|
FirstAsync(a => a.Id == bcOrder.BOOKING_ORDER_ID.Value);
|
|
|
|
|
|
|
|
|
|
if (bkOrder != null)
|
|
|
|
|
{
|
|
|
|
|
var showBKOrder = bkOrder.Adapt<BookingOrderOutput>();
|
|
|
|
|
|
|
|
|
|
var ctnList = await _bookingCtnRepository.AsQueryable().
|
|
|
|
|
Where(a => a.BILLID == bkOrder.Id).ToListAsync();
|
|
|
|
|
|
|
|
|
|
if (ctnList.Count > 0)
|
|
|
|
|
showBKOrder.ctnInputs = ctnList.Adapt<List<BookingCtnDto>>();
|
|
|
|
|
|
|
|
|
|
result.ext2 = showBKOrder;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"获取BC详情异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 通过任务主键获取BC详情
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 通过任务主键获取BC详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPkId">BC任务主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/GetInfoByTaskId")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> GetInfoByTaskId(string taskPkId)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId);
|
|
|
|
|
|
|
|
|
|
if (taskBase == null)
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息");
|
|
|
|
|
|
|
|
|
|
var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (bcOrder == null)
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPkId}无法获取BC业务信息");
|
|
|
|
|
|
|
|
|
|
var bcCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == bcOrder.PK_ID).ToList();
|
|
|
|
|
|
|
|
|
|
TaskBCShowBaseDto model = bcOrder.Adapt<TaskBCShowBaseDto>();
|
|
|
|
|
|
|
|
|
|
if (bcCtnList.Count > 0)
|
|
|
|
|
model.CtnList = bcCtnList.Adapt<List<TaskBCCTNInfoDto>>();
|
|
|
|
|
|
|
|
|
|
var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToList();
|
|
|
|
|
|
|
|
|
|
if (fileList.Count > 0)
|
|
|
|
|
model.FileList = fileList.Adapt<List<TaskFileDto>>();
|
|
|
|
|
|
|
|
|
|
model.taskStatus = taskBase.STATUS;
|
|
|
|
|
|
|
|
|
|
//生成关键信息
|
|
|
|
|
#region 生成关键信息
|
|
|
|
|
model.Keywords = new List<TaskBCShowBaseKeywordDto>();
|
|
|
|
|
|
|
|
|
|
if(bcOrder.CARRIAGE_TYPE == "DIRECT_SHIP")
|
|
|
|
|
{
|
|
|
|
|
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"承运方式:{bcOrder.CARRIAGE_TYPE_NAME}", Background = "#FFFF80",Icon= "icon-yunshu1" });
|
|
|
|
|
}
|
|
|
|
|
else if (bcOrder.CARRIAGE_TYPE == "TRANSFER_SHIP")
|
|
|
|
|
{
|
|
|
|
|
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"承运方式:{bcOrder.CARRIAGE_TYPE_NAME}", Background = "#CAF982", Icon = "icon-shuaxin" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bcOrder.BOOKING_SLOT_TYPE == "CONTRACT_ORDER")
|
|
|
|
|
{
|
|
|
|
|
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"订舱方式:{bcOrder.BOOKING_SLOT_TYPE_NAME}", Background = "#81D3F8", Icon = "icon-touzijilu" });
|
|
|
|
|
}
|
|
|
|
|
else if (bcOrder.BOOKING_SLOT_TYPE == "SPOT_ORDER")
|
|
|
|
|
{
|
|
|
|
|
model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"订舱方式:{bcOrder.BOOKING_SLOT_TYPE_NAME}", Background = "#FACD91", Icon = "icon-beizhu1" });
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.ext = model;
|
|
|
|
|
|
|
|
|
|
//如果当前BC有对应记录,则读取订舱详情
|
|
|
|
|
if (bcOrder.BOOKING_ORDER_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var bkOrder = await _bookingOrderRepository.AsQueryable().
|
|
|
|
|
FirstAsync(a => a.Id == bcOrder.BOOKING_ORDER_ID.Value);
|
|
|
|
|
|
|
|
|
|
if(bkOrder != null)
|
|
|
|
|
{
|
|
|
|
|
var showBKOrder = bkOrder.Adapt<BookingOrderOutput>();
|
|
|
|
|
|
|
|
|
|
var ctnList = await _bookingCtnRepository.AsQueryable().
|
|
|
|
|
Where(a => a.BILLID == bkOrder.Id).ToListAsync();
|
|
|
|
|
|
|
|
|
|
if (ctnList.Count > 0)
|
|
|
|
|
showBKOrder.ctnInputs = ctnList.Adapt<List<BookingCtnDto>>();
|
|
|
|
|
|
|
|
|
|
result.ext2 = showBKOrder;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"获取BC详情异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取待处理的BC任务
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取待处理的BC任务(来自邮件解析需要对应订舱,系统会根据用户的订舱台账预配)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/GetToDoBCList")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> GetToDoBCList()
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
1、优先匹配提单号一致的
|
|
|
|
|
2、判断船名航次一致的
|
|
|
|
|
*/
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, List<BookingOrder>> toDoListDict = new Dictionary<string, List<BookingOrder>>();
|
|
|
|
|
//获取所有待处理的BC任务
|
|
|
|
|
var taskList = await _taskBCInfoRepository.AsQueryable().InnerJoin<TaskBaseInfo>((a,b)=>a.TASK_ID == b.PK_ID)
|
|
|
|
|
.Where((a, b)=> !a.BOOKING_ORDER_ID.HasValue && b.STATUS == TaskStatusEnum.Create.ToString() && b.TASK_BASE_TYPE == TaskBaseTypeEnum.BC.ToString())
|
|
|
|
|
.Select((a,b)=>new { BC = a,TSK = b }).ToListAsync();
|
|
|
|
|
|
|
|
|
|
if (taskList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
|
|
{
|
|
|
|
|
var curList = await _bookingOrderRepository.AsQueryable()
|
|
|
|
|
.Where(a => a.VESSEL.Contains(tsk.BC.VESSEL) && a.VOYNO.Contains(tsk.BC.VOYNO) || a.MBLNO.Contains(tsk.BC.MBL_NO)
|
|
|
|
|
).ToListAsync();
|
|
|
|
|
|
|
|
|
|
if (curList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
toDoListDict.Add(tsk.BC.PK_ID, curList);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
toDoListDict.Add(tsk.BC.PK_ID, new List<BookingOrder>());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//这里最后清洗一下对应的订舱数据,只保留一条符合的数据
|
|
|
|
|
if (toDoListDict.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
List<Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>> tupList = new List<Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>>();
|
|
|
|
|
|
|
|
|
|
int num = 1;
|
|
|
|
|
int odNum = 1;
|
|
|
|
|
foreach (var kvp in toDoListDict)
|
|
|
|
|
{
|
|
|
|
|
var bcInfo = taskList.FirstOrDefault(a => a.BC.PK_ID == kvp.Key).BC.Adapt<TaskBCInfoDto>();
|
|
|
|
|
|
|
|
|
|
bcInfo.Indx = num;
|
|
|
|
|
|
|
|
|
|
if (kvp.Value.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var bookingOrder = kvp.Value.Select(a =>
|
|
|
|
|
{
|
|
|
|
|
if (a.MBLNO.Equals(bcInfo.MBLNo, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
return new { Sort = 90, OBJ = a };
|
|
|
|
|
}
|
|
|
|
|
else if (a.VESSEL.Equals(bcInfo.Vessel, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
&& a.VOYNO.Equals(bcInfo.VoyNo, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
return new { Sort = 80, OBJ = a };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new { Sort = 1, OBJ = a };
|
|
|
|
|
}).OrderByDescending(a => a.Sort).FirstOrDefault().OBJ.Adapt<BookingOrderBCTaskDto>();
|
|
|
|
|
|
|
|
|
|
bookingOrder.Indx = odNum;
|
|
|
|
|
bookingOrder.BCIndx = num;
|
|
|
|
|
|
|
|
|
|
bcInfo.BKOrderIndx = odNum;
|
|
|
|
|
|
|
|
|
|
odNum++;
|
|
|
|
|
|
|
|
|
|
tupList.Add(new Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>(
|
|
|
|
|
bcInfo,
|
|
|
|
|
bookingOrder
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tupList.Add(new Tuple<TaskBCInfoDto, BookingOrderBCTaskDto>(
|
|
|
|
|
bcInfo,
|
|
|
|
|
null
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
num++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.ext = tupList.Select(a=>a.Item1).ToList();
|
|
|
|
|
result.ext2 = tupList.Select(a => a.Item2).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"获取派车详情异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 任务ID下载附件
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 任务ID下载附件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPKId">BC任务主键</param>
|
|
|
|
|
/// <param name="fileCategory">附件分类代码</param>
|
|
|
|
|
/// <returns>返回数据流</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/DownloadFile")]
|
|
|
|
|
public async Task<IActionResult> DownloadFile([FromQuery] string taskPKId, [FromQuery] string fileCategory = "BC")
|
|
|
|
|
{
|
|
|
|
|
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<BookingAttachOptions>();
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
#region 检索订舱信息
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 检索订舱信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="query">检索条件</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpPost("/TaskManageBC/QueryBookingOrderList")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> QueryBookingOrderList([FromBody] BookingOrderBCQuery query)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
bool isAvailable = false;
|
|
|
|
|
|
|
|
|
|
var queryWhere = _bookingOrderRepository.AsQueryable();
|
|
|
|
|
|
|
|
|
|
#region 查询条件
|
|
|
|
|
if (query.beginETD.HasValue || query.endETD.HasValue)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
起始结束时间间隔不能超过7天
|
|
|
|
|
*/
|
|
|
|
|
DateTime beginDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
|
|
|
|
|
DateTime endDate = beginDate;
|
|
|
|
|
|
|
|
|
|
if (query.beginETD.HasValue)
|
|
|
|
|
beginDate = query.beginETD.Value;
|
|
|
|
|
|
|
|
|
|
if (query.endETD.HasValue)
|
|
|
|
|
endDate = query.endETD.Value;
|
|
|
|
|
|
|
|
|
|
if (endDate > beginDate.AddDays(7))
|
|
|
|
|
throw Oops.Oh($"船期的日期范围不能超过7天");
|
|
|
|
|
|
|
|
|
|
endDate = endDate.AddDays(1);
|
|
|
|
|
|
|
|
|
|
queryWhere = queryWhere.Where(a => a.ETD >= beginDate && a.ETD < endDate);
|
|
|
|
|
|
|
|
|
|
isAvailable = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (query.beginCreated.HasValue || query.endCreated.HasValue)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
起始结束时间间隔不能超过7天
|
|
|
|
|
*/
|
|
|
|
|
DateTime beginDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
|
|
|
|
|
DateTime endDate = beginDate;
|
|
|
|
|
|
|
|
|
|
if (query.beginCreated.HasValue)
|
|
|
|
|
beginDate = query.beginCreated.Value;
|
|
|
|
|
|
|
|
|
|
if (query.endCreated.HasValue)
|
|
|
|
|
endDate = query.endCreated.Value;
|
|
|
|
|
|
|
|
|
|
if (endDate > beginDate.AddDays(7))
|
|
|
|
|
throw Oops.Oh($"制单的日期范围不能超过7天");
|
|
|
|
|
|
|
|
|
|
endDate = endDate.AddDays(1);
|
|
|
|
|
|
|
|
|
|
queryWhere = queryWhere.Where(a => a.CreatedTime >= beginDate && a.CreatedTime < endDate);
|
|
|
|
|
|
|
|
|
|
isAvailable = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(query.mblNo))
|
|
|
|
|
{
|
|
|
|
|
queryWhere = queryWhere.Where(a => a.MBLNO.Contains(query.mblNo));
|
|
|
|
|
|
|
|
|
|
isAvailable = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(query.custNo))
|
|
|
|
|
{
|
|
|
|
|
queryWhere = queryWhere.Where(a => a.CUSTNO.Contains(query.custNo));
|
|
|
|
|
|
|
|
|
|
isAvailable = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(query.vessel))
|
|
|
|
|
{
|
|
|
|
|
queryWhere = queryWhere.Where(a => a.VESSEL.Contains(query.vessel));
|
|
|
|
|
|
|
|
|
|
isAvailable = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(query.voyno))
|
|
|
|
|
{
|
|
|
|
|
queryWhere = queryWhere.Where(a => a.VOYNO.Contains(query.voyno));
|
|
|
|
|
|
|
|
|
|
isAvailable = true;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
if (!isAvailable)
|
|
|
|
|
throw Oops.Oh($"查询条件不能为空");
|
|
|
|
|
|
|
|
|
|
var list = await queryWhere.OrderBy(a => a.CreatedTime)
|
|
|
|
|
.Take(query.topNum).ToListAsync();
|
|
|
|
|
|
|
|
|
|
var bkList = list.Adapt<List<BookingOrderBCTaskDto>>();
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.ext = bkList;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"查询失败,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 转移任务(将任务指定给其他人)
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 转移任务(将任务指定给其他人)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPKId">BC任务主键</param>
|
|
|
|
|
/// <param name="userId">用户ID</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/TransferTask")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> TransferTask([FromQuery] string taskPKId, [FromQuery] long userId)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
1、如果当前任务是公共任务,则更新为相关人后,变更任务为个人。
|
|
|
|
|
*/
|
|
|
|
|
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId);
|
|
|
|
|
if (bcTaskInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(userId < 0)
|
|
|
|
|
throw Oops.Oh($"指定用户ID不能为空");
|
|
|
|
|
|
|
|
|
|
var targetUserId = _sysUserRepository.AsQueryable().First(u => u.Id == userId);
|
|
|
|
|
|
|
|
|
|
if (targetUserId == null)
|
|
|
|
|
throw Oops.Oh($"指定用户不存在");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bcTaskInfo.IS_PUBLIC == 1)
|
|
|
|
|
{
|
|
|
|
|
bcTaskInfo.IS_PUBLIC = 0;
|
|
|
|
|
|
|
|
|
|
bcTaskInfo.CreatedUserId = targetUserId.Id;
|
|
|
|
|
bcTaskInfo.CreatedUserName = targetUserId.Name;
|
|
|
|
|
|
|
|
|
|
bcTaskInfo.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcTaskInfo.UpdatedUserId = targetUserId.Id;
|
|
|
|
|
bcTaskInfo.UpdatedUserName = targetUserId.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(bcTaskInfo).IgnoreColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.TenantId,
|
|
|
|
|
it.CreatedTime,
|
|
|
|
|
it.IsDeleted,
|
|
|
|
|
it.TASK_NO,
|
|
|
|
|
it.TASK_TYPE,
|
|
|
|
|
it.TASK_SOURCE
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bcTaskInfo.CreatedUserId = targetUserId.Id;
|
|
|
|
|
bcTaskInfo.CreatedUserName = targetUserId.Name;
|
|
|
|
|
|
|
|
|
|
bcTaskInfo.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcTaskInfo.UpdatedUserId = targetUserId.Id;
|
|
|
|
|
bcTaskInfo.UpdatedUserName = targetUserId.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(bcTaskInfo).IgnoreColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.TenantId,
|
|
|
|
|
it.CreatedTime,
|
|
|
|
|
it.IsDeleted,
|
|
|
|
|
it.TASK_NO,
|
|
|
|
|
it.TASK_TYPE,
|
|
|
|
|
it.TASK_SOURCE
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "成功";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"转移任务失败,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 生成订舱或舱位
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成订舱或舱位
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="model">生成订舱或者舱位请求</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpPost("/TaskManageBC/CreateBookingAndSlot")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> CreateBookingAndSlot([FromBody] BookingOrSlotGenerateDto model)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
1、GEN_BOOKING_SLOT-生成舱位和订舱
|
|
|
|
|
(1)生成舱位
|
|
|
|
|
(2)生成海运订舱
|
|
|
|
|
(3)更新舱位库存
|
|
|
|
|
(4)更新BC任务
|
|
|
|
|
2、GEN_BOOKING-只生成订舱
|
|
|
|
|
(1)生成海运订舱
|
|
|
|
|
(4)更新BC任务
|
|
|
|
|
3、GEN_SLOT-只生成舱位
|
|
|
|
|
(1)生成舱位
|
|
|
|
|
(4)更新BC任务
|
|
|
|
|
3、GEN_SLOT-只生成舱位
|
|
|
|
|
(1)查找订舱记录
|
|
|
|
|
(3)更新舱位库存
|
|
|
|
|
(4)更新BC任务
|
|
|
|
|
*/
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.BCTaskId))
|
|
|
|
|
throw Oops.Oh($"BC任务主键不能为空");
|
|
|
|
|
|
|
|
|
|
//生成方式(GEN_BOOKING_SLOT-生成舱位和订舱;GEN_BOOKING-只生成订舱;GEN_SLOT-只生成舱位;GEN_EXIST_BOOKING-匹配指定的订舱)
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.GenerateMethod))
|
|
|
|
|
throw Oops.Oh($"生成方式不能为空,需要指定一种生成方式");
|
|
|
|
|
|
|
|
|
|
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == model.BCTaskId);
|
|
|
|
|
if (bcTaskInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"任务主键{model.BCTaskId}无法获取业务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == bcTaskInfo.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (bcOrder == null)
|
|
|
|
|
throw Oops.Oh($"任务主键{model.BCTaskId}无法获取BC业务信息");
|
|
|
|
|
|
|
|
|
|
var bcCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == bcOrder.PK_ID).ToList();
|
|
|
|
|
|
|
|
|
|
var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcTaskInfo.PK_ID).ToList();
|
|
|
|
|
|
|
|
|
|
if (model.GenerateMethod != "UPD_BOOKING")
|
|
|
|
|
{
|
|
|
|
|
if (bcOrder.BOOKING_ORDER_ID.HasValue && bcOrder.BOOKING_ORDER_ID.Value > 0)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"当前BC任务已生成订舱订单,不能重复生成");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (model.GenerateMethod == "GEN_BOOKING_SLOT")
|
|
|
|
|
{
|
|
|
|
|
#region 推送舱位、推送订舱
|
|
|
|
|
//推送舱位
|
|
|
|
|
long bookingSlotId = 0;
|
|
|
|
|
|
|
|
|
|
if (bcOrder.BOOKING_SLOT_ID.HasValue && bcOrder.BOOKING_SLOT_ID.Value > 0)
|
|
|
|
|
{
|
|
|
|
|
//bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value;
|
|
|
|
|
throw Oops.Oh($"生成舱位失败,舱位已存在");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//触发生成舱位
|
|
|
|
|
bookingSlotId = await GenerateBookingSlot(bcOrder, bcCtnList, fileList);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成舱位完成,bookingSlotId={bookingSlotId} taskid={bcOrder.TASK_ID}");
|
|
|
|
|
|
|
|
|
|
if(bookingSlotId < 1)
|
|
|
|
|
throw Oops.Oh($"生成舱位失败");
|
|
|
|
|
|
|
|
|
|
//推送订舱订单
|
|
|
|
|
var bookingOrderId = await GenerateBookingOrder(bcOrder, bcCtnList, fileList, model);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成订舱订单完成,bookingOrderId={bookingOrderId} taskid={bcOrder.TASK_ID}");
|
|
|
|
|
|
|
|
|
|
if (bookingOrderId < 1)
|
|
|
|
|
throw Oops.Oh($"生成订舱订单失败");
|
|
|
|
|
|
|
|
|
|
List<BookingSlotBaseWithCtnDto> slots = new List<BookingSlotBaseWithCtnDto>();
|
|
|
|
|
|
|
|
|
|
//检索舱位信息
|
|
|
|
|
var slotInfo = _bookingSlotService.Detail(bookingSlotId).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
BookingSlotBaseWithCtnDto baseInfo = slotInfo.Adapt<BookingSlotBaseWithCtnDto>();
|
|
|
|
|
baseInfo.Id = bookingSlotId;
|
|
|
|
|
baseInfo.CtnList = slotInfo.CtnList.Adapt<List<BookingSlotCtnDto>>();
|
|
|
|
|
|
|
|
|
|
slots.Add(baseInfo);
|
|
|
|
|
|
|
|
|
|
//对应订舱和舱位关系
|
|
|
|
|
var allocRlt = await _bookingSlotService.ImportSlots(slots, bookingOrderId, false);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成订舱和舱位关系完成,allocRlt={JSON.Serialize(allocRlt)} taskid={bcOrder.TASK_ID}");
|
|
|
|
|
|
|
|
|
|
if (!allocRlt.isSuccess)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"生成订舱和舱位关系失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcOrder.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (bcEntity == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未获取有效任务BC失败,更新失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bcEntity.BOOKING_ORDER_ID = bookingOrderId;
|
|
|
|
|
bcEntity.BOOKING_SLOT_ID = bookingSlotId;
|
|
|
|
|
bcEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
//更新任务BC
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_ORDER_ID,
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID);
|
|
|
|
|
|
|
|
|
|
if (taskEntity == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未获取有效任务记录,更新失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 更新任务
|
|
|
|
|
//如果是公共任务,需要变成个人任务 RealUserId = 当前操作人
|
|
|
|
|
if (taskEntity.IS_PUBLIC == 1)
|
|
|
|
|
{
|
|
|
|
|
taskEntity.IS_PUBLIC = 0;
|
|
|
|
|
taskEntity.RealUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.RealUserName = UserManager.Name;
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.IS_PUBLIC,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName,
|
|
|
|
|
it.RealUserId,
|
|
|
|
|
it.RealUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
var currBCOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcEntity.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (currBCOrder != null && model.IsDirectSend)
|
|
|
|
|
{
|
|
|
|
|
//异步推送邮件
|
|
|
|
|
var mailRlt = await GenerateSendEmail(currBCOrder, bcTaskInfo, model.usePersonalEmailSend);
|
|
|
|
|
|
|
|
|
|
if (!mailRlt.succ)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"邮件推送失败,原因:{mailRlt.msg},可以任务编辑页面重新发送邮件");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
else if (model.GenerateMethod == "GEN_BOOKING")
|
|
|
|
|
{
|
|
|
|
|
#region 推送订舱
|
|
|
|
|
long bookingId = 0;
|
|
|
|
|
long bookingSlotId = 0;
|
|
|
|
|
|
|
|
|
|
if (bcOrder.BOOKING_ORDER_ID.HasValue && bcOrder.BOOKING_ORDER_ID.Value > 0)
|
|
|
|
|
{
|
|
|
|
|
//bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value;
|
|
|
|
|
throw Oops.Oh($"生成订舱订单失败,订舱订单已存在");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!bcOrder.BOOKING_SLOT_ID.HasValue || bcOrder.BOOKING_SLOT_ID.Value < 1)
|
|
|
|
|
{
|
|
|
|
|
//bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value;
|
|
|
|
|
throw Oops.Oh($"生成订舱订单失败,舱位未生成不能直接生成订舱订单");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value;
|
|
|
|
|
|
|
|
|
|
//推送订舱订单
|
|
|
|
|
var bookingOrderId = await GenerateBookingOrder(bcOrder, bcCtnList, fileList, model);
|
|
|
|
|
|
|
|
|
|
List<BookingSlotBaseWithCtnDto> slots = new List<BookingSlotBaseWithCtnDto>();
|
|
|
|
|
|
|
|
|
|
//检索舱位信息
|
|
|
|
|
var slotInfo = _bookingSlotService.Detail(bookingSlotId).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
BookingSlotBaseWithCtnDto baseInfo = slotInfo.Adapt<BookingSlotBaseWithCtnDto>();
|
|
|
|
|
baseInfo.Id = bookingSlotId;
|
|
|
|
|
baseInfo.CtnList = slotInfo.CtnList.Adapt<List<BookingSlotCtnDto>>();
|
|
|
|
|
|
|
|
|
|
slots.Add(baseInfo);
|
|
|
|
|
|
|
|
|
|
//对应订舱和舱位关系
|
|
|
|
|
var allocRlt = await _bookingSlotService.ImportSlots(slots, bookingOrderId, false);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成订舱和舱位关系完成,allocRlt={JSON.Serialize(allocRlt)} taskid={bcOrder.TASK_ID}");
|
|
|
|
|
|
|
|
|
|
if (!allocRlt.isSuccess)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"生成订舱和舱位关系失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcOrder.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (bcEntity == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未获取有效任务BC失败,更新失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bcEntity.BOOKING_ORDER_ID = bookingOrderId;
|
|
|
|
|
bcEntity.BOOKING_SLOT_ID = bookingSlotId;
|
|
|
|
|
bcEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
//更新任务BC
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_ORDER_ID,
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID);
|
|
|
|
|
|
|
|
|
|
if (taskEntity == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未获取有效任务记录,更新失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 更新任务
|
|
|
|
|
//如果是公共任务,需要变成个人任务 RealUserId = 当前操作人
|
|
|
|
|
if (taskEntity.IS_PUBLIC == 1)
|
|
|
|
|
{
|
|
|
|
|
taskEntity.IS_PUBLIC = 0;
|
|
|
|
|
taskEntity.RealUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.RealUserName = UserManager.Name;
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.IS_PUBLIC,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName,
|
|
|
|
|
it.RealUserId,
|
|
|
|
|
it.RealUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
var currBCOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcEntity.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (currBCOrder != null && model.IsDirectSend)
|
|
|
|
|
{
|
|
|
|
|
//异步推送邮件
|
|
|
|
|
var mailRlt = await GenerateSendEmail(currBCOrder, bcTaskInfo, model.usePersonalEmailSend);
|
|
|
|
|
|
|
|
|
|
if (!mailRlt.succ)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"邮件推送失败,原因:{mailRlt.msg},可以任务编辑页面重新发送邮件");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
else if (model.GenerateMethod == "GEN_SLOT")
|
|
|
|
|
{
|
|
|
|
|
long bookingSlotId = 0;
|
|
|
|
|
|
|
|
|
|
if (bcOrder.BOOKING_SLOT_ID.HasValue && bcOrder.BOOKING_SLOT_ID.Value > 0)
|
|
|
|
|
{
|
|
|
|
|
//bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value;
|
|
|
|
|
throw Oops.Oh($"生成舱位失败,舱位已存在");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//触发生成舱位
|
|
|
|
|
bookingSlotId = await GenerateBookingSlot(bcOrder, bcCtnList, fileList);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成舱位完成,bookingSlotId={bookingSlotId} taskid={bcOrder.TASK_ID}");
|
|
|
|
|
|
|
|
|
|
if (bookingSlotId < 1)
|
|
|
|
|
throw Oops.Oh($"生成舱位失败");
|
|
|
|
|
|
|
|
|
|
var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcOrder.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (bcEntity == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未获取有效任务BC失败,更新失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bcEntity.BOOKING_SLOT_ID = bookingSlotId;
|
|
|
|
|
bcEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
//更新任务BC
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID);
|
|
|
|
|
|
|
|
|
|
if (taskEntity == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未获取有效任务记录,更新失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 更新任务
|
|
|
|
|
//如果是公共任务,需要变成个人任务 RealUserId = 当前操作人
|
|
|
|
|
if (taskEntity.IS_PUBLIC == 1)
|
|
|
|
|
{
|
|
|
|
|
taskEntity.IS_PUBLIC = 0;
|
|
|
|
|
taskEntity.RealUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.RealUserName = UserManager.Name;
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.IS_PUBLIC,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName,
|
|
|
|
|
it.RealUserId,
|
|
|
|
|
it.RealUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
else if (model.GenerateMethod == "UPD_BOOKING")
|
|
|
|
|
{
|
|
|
|
|
//推送订舱订单
|
|
|
|
|
var bookingOrderId = await UpdateBookingOrder(bcOrder, bcCtnList, fileList, model);
|
|
|
|
|
|
|
|
|
|
var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcOrder.TASK_ID);
|
|
|
|
|
|
|
|
|
|
if (taskEntity == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未获取有效任务记录,更新失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 更新任务
|
|
|
|
|
//如果是公共任务,需要变成个人任务 RealUserId = 当前操作人
|
|
|
|
|
if (taskEntity.IS_PUBLIC == 1)
|
|
|
|
|
{
|
|
|
|
|
taskEntity.IS_PUBLIC = 0;
|
|
|
|
|
taskEntity.RealUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.RealUserName = UserManager.Name;
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.IS_PUBLIC,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName,
|
|
|
|
|
it.RealUserId,
|
|
|
|
|
it.RealUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
taskEntity.UpdatedTime = DateTime.Now;
|
|
|
|
|
taskEntity.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
var currBCOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcOrder.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (currBCOrder != null && model.IsDirectSend)
|
|
|
|
|
{
|
|
|
|
|
//异步推送邮件
|
|
|
|
|
var mailRlt = await GenerateSendEmail(currBCOrder, bcTaskInfo, model.usePersonalEmailSend);
|
|
|
|
|
|
|
|
|
|
if (!mailRlt.succ)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"邮件推送失败,原因:{mailRlt.msg},可以任务编辑页面重新发送邮件");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "成功";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"生成订舱或舱位失败,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 生成舱位
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成舱位
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskBCInfo">BC任务详情</param>
|
|
|
|
|
/// <param name="taskBCCtnList">BC任务集装箱列表</param>
|
|
|
|
|
/// <param name="taskFileList">BC任务附件列表</param>
|
|
|
|
|
/// <returns>返回舱位ID</returns>
|
|
|
|
|
private async Task<long> GenerateBookingSlot(TaskBCInfo taskBCInfo, List<TaskBCCTNInfo> taskBCCtnList, List<TaskFileInfo> taskFileList,string opType = "add")
|
|
|
|
|
{
|
|
|
|
|
long id = 0;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var carrierInfo = _cache.GetAllCodeCarrier().GetAwaiter().GetResult()
|
|
|
|
|
.Where(t => t.Code.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|| t.EnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|| t.CnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BookingSlotBaseApiDto slotModel = new BookingSlotBaseApiDto
|
|
|
|
|
{
|
|
|
|
|
DataObj = new BookingSlotBaseApiSaveDto
|
|
|
|
|
{
|
|
|
|
|
CARRIERID = taskBCInfo.CARRIERID,
|
|
|
|
|
CARRIER = carrierInfo.CnName?.Trim(),
|
|
|
|
|
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<BookingSlotCtnSaveInput>()
|
|
|
|
|
},
|
|
|
|
|
OpType = opType
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
|
|
|
|
|
|
|
|
|
|
if (taskBCCtnList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
taskBCCtnList.ForEach(t =>
|
|
|
|
|
{
|
|
|
|
|
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
|
|
|
|
|
a.Name.Equals(t.CTNALL, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
BookingSlotCtnSaveInput ctn = new BookingSlotCtnSaveInput
|
|
|
|
|
{
|
|
|
|
|
CTNCODE = ctnCode?.Code,
|
|
|
|
|
CTNALL = t.CTNALL,
|
|
|
|
|
CTNNUM = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
slotModel.DataObj.CtnList.Add(ctn);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var opt = App.GetOptions<BookingAttachOptions>();
|
|
|
|
|
var dirAbs = opt.basePath;
|
|
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
|
|
{
|
|
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
id = await _bookingSlotService.InnerApiReceive(slotModel, dynameFile, dynameNoticeFile);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成舱位异常,原因:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 生成订舱
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成订舱
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskBCInfo">BC任务详情</param>
|
|
|
|
|
/// <param name="taskBCCtnList">BC任务集装箱列表</param>
|
|
|
|
|
/// <param name="taskFileList">BC任务附件列表</param>
|
|
|
|
|
/// <param name="generateModel">订舱请求详情</param>
|
|
|
|
|
/// <returns>返回订舱ID</returns>
|
|
|
|
|
private async Task<long> GenerateBookingOrder(TaskBCInfo taskBCInfo, List<TaskBCCTNInfo> taskBCCtnList, List<TaskFileInfo> taskFileList,
|
|
|
|
|
BookingOrSlotGenerateDto generateModel)
|
|
|
|
|
{
|
|
|
|
|
long id = 0;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
1、新增订舱
|
|
|
|
|
2、推送服务项目
|
|
|
|
|
3、推送附件
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
var carrierInfo = _cache.GetAllCodeCarrier().GetAwaiter().GetResult()
|
|
|
|
|
.Where(t => t.Code.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|| t.EnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|| t.CnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
SaveBookingOrderInput bkModel = new SaveBookingOrderInput
|
|
|
|
|
{
|
|
|
|
|
CUSTOMERID = generateModel.CustomerId,
|
|
|
|
|
CUSTOMERNAME = generateModel.CustomerName,
|
|
|
|
|
CARRIERID = carrierInfo.Code?.Trim(),
|
|
|
|
|
CARRIER = carrierInfo.CnName?.Trim(),
|
|
|
|
|
MBLNO = taskBCInfo.MBL_NO.ToUpper().Trim(),
|
|
|
|
|
CONTRACTNO = !string.IsNullOrWhiteSpace(taskBCInfo.CONTRACTNO) ? taskBCInfo.CONTRACTNO : "",
|
|
|
|
|
VESSEL = taskBCInfo.VESSEL.ToUpper().Trim(),
|
|
|
|
|
VOYNO = taskBCInfo.VOYNO.ToUpper().Trim(),
|
|
|
|
|
VOYNOINNER = taskBCInfo.VOYNO.ToUpper().Trim(),
|
|
|
|
|
ETD = taskBCInfo.ETD,
|
|
|
|
|
ETA = taskBCInfo.ETA,
|
|
|
|
|
SALEID = generateModel.SaleId.ToString(),
|
|
|
|
|
SALE = generateModel.SaleName,
|
|
|
|
|
OPID = generateModel.OpId.ToString(),
|
|
|
|
|
OP = generateModel.OpName,
|
|
|
|
|
DOCID = generateModel.DocId.ToString(),
|
|
|
|
|
DOC = generateModel.DocName,
|
|
|
|
|
ROUTEID = generateModel.RouteID.ToString(),
|
|
|
|
|
ROUTE = generateModel.Route,
|
|
|
|
|
CZRemark = generateModel.CZRemark,
|
|
|
|
|
ShenQingXiangShi = generateModel.ShenQingXiangShi,
|
|
|
|
|
LineManageID = generateModel.LineManageID.ToString(),
|
|
|
|
|
LineName = generateModel.LineManage,
|
|
|
|
|
CLOSEVGMDATE = taskBCInfo.VGM_CUTOFF_TIME,
|
|
|
|
|
CLOSINGDATE = taskBCInfo.CY_CUTOFF_TIME,
|
|
|
|
|
CLOSEDOCDATE = taskBCInfo.CUT_SINGLE_TIME,
|
|
|
|
|
CUSTSERVICEID = generateModel.CustServiceId.HasValue? generateModel.CustServiceId.Value.ToString(): null,
|
|
|
|
|
CUSTSERVICE = generateModel.CustServiceName,
|
|
|
|
|
|
|
|
|
|
ctnInputs = new List<BookingCtnDto>()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
|
|
|
|
|
|
|
|
|
|
if (taskBCCtnList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
taskBCCtnList.ForEach(t =>
|
|
|
|
|
{
|
|
|
|
|
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
|
|
|
|
|
a.Name.Equals(t.CTNALL, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
BookingCtnDto ctn = new BookingCtnDto
|
|
|
|
|
{
|
|
|
|
|
CTNCODE = ctnCode?.Code,
|
|
|
|
|
CTNALL = t.CTNALL,
|
|
|
|
|
CTNNUM = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bkModel.ctnInputs.Add(ctn);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bkRlt = await _bookingOrderService.Save(bkModel);
|
|
|
|
|
|
|
|
|
|
id = bkRlt.Id;
|
|
|
|
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
|
|
|
|
if (id > 0)
|
|
|
|
|
{
|
|
|
|
|
//这里如果指定了委托单位的邮件联系人,则推送订舱联系人
|
|
|
|
|
if (generateModel.CustomerContactList != null && generateModel.CustomerContactList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var bookingContactList = _bookingOrderContactRepository.AsQueryable()
|
|
|
|
|
.Where(a => a.BookingId == id && !a.IsDeleted).ToList();
|
|
|
|
|
|
|
|
|
|
var djyCustomerInfo = _djyCustomerService.Detail(new GetDjyCustomerInput { Id = generateModel.CustomerId.Value })
|
|
|
|
|
.GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
generateModel.CustomerContactList.ForEach(contact =>
|
|
|
|
|
{
|
|
|
|
|
DjyCustomerContactOutput djyCustomerContactMan = null;
|
|
|
|
|
|
|
|
|
|
if (djyCustomerInfo.Contacts != null && djyCustomerInfo.Contacts.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
djyCustomerContactMan = djyCustomerInfo.Contacts.FirstOrDefault(a =>
|
|
|
|
|
a.Id == contact.CustomerContactId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (djyCustomerContactMan != null)
|
|
|
|
|
{
|
|
|
|
|
var bookingContact = bookingContactList
|
|
|
|
|
.FirstOrDefault(x => x.Email.Equals(djyCustomerContactMan.Email, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
if (bookingContact == null)
|
|
|
|
|
{
|
|
|
|
|
bookingContact = new BookingOrderContact
|
|
|
|
|
{
|
|
|
|
|
Name = djyCustomerContactMan.Name,
|
|
|
|
|
BookingId = id,
|
|
|
|
|
Email = djyCustomerContactMan.Email,
|
|
|
|
|
Remark = djyCustomerContactMan.Remark,
|
|
|
|
|
CreatedTime = DateTime.Now,
|
|
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
|
|
CreatedUserName = UserManager.Name
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_bookingOrderContactRepository.Insert(bookingContact);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bookingContact.Name = djyCustomerContactMan.Name;
|
|
|
|
|
bookingContact.Email = djyCustomerContactMan.Email;
|
|
|
|
|
bookingContact.Remark = djyCustomerContactMan.Remark;
|
|
|
|
|
bookingContact.UpdatedTime = DateTime.Now;
|
|
|
|
|
bookingContact.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bookingContact.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
_bookingOrderContactRepository.AsUpdateable(bookingContact).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.Name,
|
|
|
|
|
it.Email,
|
|
|
|
|
it.Remark,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommand();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (generateModel.ProjectList != null && generateModel.ProjectList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
ModifyServiceProjectDto projectDto = new ModifyServiceProjectDto
|
|
|
|
|
{
|
|
|
|
|
BookingId = id,
|
|
|
|
|
ProjectCodes = generateModel.ProjectList.Distinct().ToArray(),
|
|
|
|
|
};
|
|
|
|
|
//写入服务项目
|
|
|
|
|
var prjRlt = await _bookingValueAddedService.SaveServiceProject(projectDto);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"推送订舱的服务项目完成 id={id} rlt={JSON.Serialize(prjRlt)}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var opt = App.GetOptions<BookingAttachOptions>();
|
|
|
|
|
var dirAbs = opt.basePath;
|
|
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
|
|
{
|
|
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
taskFileList.ForEach(file =>
|
|
|
|
|
{
|
|
|
|
|
if (file.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString())
|
|
|
|
|
{
|
|
|
|
|
var fileFullPath = Path.Combine(dirAbs, file.FILE_PATH);
|
|
|
|
|
|
|
|
|
|
if (File.Exists(fileFullPath))
|
|
|
|
|
{
|
|
|
|
|
//如果确认文件读取成功
|
|
|
|
|
var bookFilePath = FileAttachHelper.MoveFile(id.ToString(), fileFullPath, batchNo
|
|
|
|
|
, false, null, true).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
//将格式单附件写入订舱的附件
|
|
|
|
|
SaveEDIFile(id, bookFilePath, new System.IO.FileInfo(bookFilePath).Name, taskBCInfo.TenantId.Value,
|
|
|
|
|
CONST_BC_FILE_CODE, CONST_BC_FILE_NAME).GetAwaiter();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (file.FILE_CATEGORY == TaskFileCategoryEnum.BC_NOTICE.ToString())
|
|
|
|
|
{
|
|
|
|
|
var fileFullPath = Path.Combine(dirAbs, file.FILE_PATH);
|
|
|
|
|
|
|
|
|
|
if (File.Exists(fileFullPath))
|
|
|
|
|
{
|
|
|
|
|
//如果确认文件读取成功
|
|
|
|
|
var bookFilePath = FileAttachHelper.MoveFile(id.ToString(), fileFullPath, batchNo
|
|
|
|
|
, false, "bcnoticefile",true).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
//将格式单附件写入订舱的附件
|
|
|
|
|
SaveEDIFile(id, bookFilePath, new System.IO.FileInfo(bookFilePath).Name, taskBCInfo.TenantId.Value,
|
|
|
|
|
CONST_BC_NOTICE_FILE_CODE, CONST_BC_NOTICE_FILE_NAME).GetAwaiter();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成订舱成功 id={id}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成订舱异常,原因:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 取消任务
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取消任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPKId">BC任务主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/CancelTask")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> CancelTask([FromQuery] string taskPKId)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var bcTaskInfo = await _taskBaseRepository.AsQueryable().FirstAsync(u => u.PK_ID == taskPKId);
|
|
|
|
|
if (bcTaskInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bcTaskInfo.IsDeleted = true;
|
|
|
|
|
bcTaskInfo.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcTaskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcTaskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(bcTaskInfo).IgnoreColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.TenantId,
|
|
|
|
|
it.CreatedTime,
|
|
|
|
|
it.CreatedUserId,
|
|
|
|
|
it.CreatedUserName,
|
|
|
|
|
it.IsDeleted,
|
|
|
|
|
it.TASK_NO,
|
|
|
|
|
it.TASK_TYPE,
|
|
|
|
|
it.TASK_SOURCE
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "成功";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"取消任务失败,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取服务项目列表
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取服务项目列表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/GetProjectList")]
|
|
|
|
|
public async Task<List<ServiceProjectBaseDto>> GetProjectList()
|
|
|
|
|
{
|
|
|
|
|
List<ServiceProjectBaseDto> list = new List<ServiceProjectBaseDto>();
|
|
|
|
|
|
|
|
|
|
return await _serviceWorkFlowBaseService.GetEnableProjectList(UserManager.TENANT_ID.ToString());
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 异步写入附件表
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 异步写入附件表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="boookId">订舱ID</param>
|
|
|
|
|
/// <param name="FilePath">文件路径</param>
|
|
|
|
|
/// <param name="fileName">文件名</param>
|
|
|
|
|
/// <param name="tenantId">租户ID</param>
|
|
|
|
|
/// <param name="fileTypeCode">附件类型代码</param>
|
|
|
|
|
/// <param name="fileTypeName">附件类型名称</param>
|
|
|
|
|
/// <param name="moudle">附件模块代码</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[NonAction]
|
|
|
|
|
private async Task SaveEDIFile(long boookId, string FilePath, string fileName, long tenantId,
|
|
|
|
|
string fileTypeCode = "bc", string fileTypeName = "Booking Confirmation",string moudle = "BookingSlot")
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
直接将附件信息写入附件表
|
|
|
|
|
*/
|
|
|
|
|
//EDI文件
|
|
|
|
|
var bookFile = new BookingFile
|
|
|
|
|
{
|
|
|
|
|
Id = YitIdHelper.NextId(),
|
|
|
|
|
FileName = fileName,
|
|
|
|
|
FilePath = FilePath,
|
|
|
|
|
TypeCode = fileTypeCode,
|
|
|
|
|
TypeName = fileTypeName,
|
|
|
|
|
BookingId = boookId,
|
|
|
|
|
TenantId = tenantId,
|
|
|
|
|
Moudle = moudle
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await _bookingFileRepository.InsertAsync(bookFile);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 生成并推送邮件
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成并推送邮件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskBCInfo">BC任务详情</param>
|
|
|
|
|
/// <param name="bcTaskInfo">主任务详情</param>
|
|
|
|
|
/// <param name="usePersonalEmailSend">是否默认使用用户个人邮箱发送</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
private async Task<TaskManageOrderResultDto> GenerateSendEmail(TaskBCInfo taskBCInfo, TaskBaseInfo bcTaskInfo, bool usePersonalEmailSend = false)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
1、提取邮件接收人、通过订舱的委托客户获取联系人信息(提取联系人中备注是BCNotice的邮箱)
|
|
|
|
|
2、提取当票订舱对应的操作人邮箱、通过订舱的委托客户获取操作OP的邮箱
|
|
|
|
|
3、读取用户邮箱配置,主要提取显示名称BCNotice的邮箱,用来作为公共邮箱来发送邮件。
|
|
|
|
|
4、读取邮件模板,填充详情。
|
|
|
|
|
5、推送邮件给邮件接收人
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
//读取订舱数据
|
|
|
|
|
var bookingOrderEntity = _bookingOrderRepository.AsQueryable().Filter(null, true)
|
|
|
|
|
.First(a => a.Id == taskBCInfo.BOOKING_ORDER_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().Filter(null, true)
|
|
|
|
|
.Where(a => a.BookingId == taskBCInfo.BOOKING_ORDER_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().Filter(null, true).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}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//提取当前公共邮箱的配置
|
|
|
|
|
DjyUserMailAccount publicMailAccount = null;
|
|
|
|
|
|
|
|
|
|
if(usePersonalEmailSend)
|
|
|
|
|
{
|
|
|
|
|
publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.CreatedUserId == UserManager.UserId
|
|
|
|
|
&& x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//这个是公共邮箱配置
|
|
|
|
|
publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.TenantId == UserManager.TENANT_ID && x.ShowName == "PublicSend"
|
|
|
|
|
&& x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (publicMailAccount == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"提取公共邮箱配置失败,请在用户邮箱账号管理增加配置显示名为PublicSend或者配置个人邮箱");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"提取当前公共邮箱的配置完成,id={publicMailAccount.Id}");
|
|
|
|
|
|
|
|
|
|
string emailTitle = $"Booking Confirmation : {taskBCInfo.MBL_NO}";
|
|
|
|
|
|
|
|
|
|
string filePath = string.Empty;
|
|
|
|
|
|
|
|
|
|
SysUser opUserInfo = null;
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(bookingOrderEntity.OPID) && Regex.IsMatch(bookingOrderEntity.OPID, "[0-9]+"))
|
|
|
|
|
opUserInfo = _sysUserRepository.AsQueryable().Filter(null, true).First(u => u.Id == long.Parse(bookingOrderEntity.OPID));
|
|
|
|
|
|
|
|
|
|
if (taskBCInfo.BUSI_TYPE == "BookingAmendment")
|
|
|
|
|
{
|
|
|
|
|
emailTitle = $"【变更】Booking Amendment : {taskBCInfo.MBL_NO}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//读取邮件模板并填充数据
|
|
|
|
|
string emailHtml = string.Empty;
|
|
|
|
|
|
|
|
|
|
if (taskBCInfo.BUSI_TYPE == "BookingAmendment")
|
|
|
|
|
{
|
|
|
|
|
emailHtml = GenerateSendEmailHtmlAmendment(taskBCInfo, opUserInfo, UserManager.TENANT_NAME).GetAwaiter().GetResult();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
emailHtml = GenerateSendEmailHtml(taskBCInfo, opUserInfo, UserManager.TENANT_NAME).GetAwaiter().GetResult();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成邮件BODY,结果:{emailHtml}");
|
|
|
|
|
|
|
|
|
|
TaskFileInfo fileInfo = null;
|
|
|
|
|
|
|
|
|
|
if (bcTaskInfo.TASK_BASE_TYPE == TaskBaseTypeEnum.BC.ToString())
|
|
|
|
|
{
|
|
|
|
|
fileInfo = _taskFileRepository.AsQueryable().Filter(null, true).Where(a => a.TASK_PKID == taskBCInfo.TASK_ID && a.FILE_CATEGORY.Contains("BC_NOTICE"))
|
|
|
|
|
.OrderByDescending(a => a.CreatedTime).First();
|
|
|
|
|
}
|
|
|
|
|
else if (bcTaskInfo.TASK_BASE_TYPE == TaskBaseTypeEnum.BC_MODIFY.ToString())
|
|
|
|
|
{
|
|
|
|
|
fileInfo = _taskFileRepository.AsQueryable().Filter(null, true).Where(a => a.TASK_PKID == taskBCInfo.TASK_ID && a.FILE_CATEGORY.Contains("BC_MODIFY_NOTICE"))
|
|
|
|
|
.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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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<AttachesInfo>()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成请求邮件参数,结果:{JSON.Serialize(emailApiUserDefinedDto)}");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//推送邮件
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"推送邮件失败,异常:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"推送邮件失败,{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 通过邮件模板生成HTML
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 通过邮件模板生成HTML
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskBCInfo">BC任务详情</param>
|
|
|
|
|
/// <param name="opUserInfo">订舱OP详情</param>
|
|
|
|
|
/// <param name="tenantName">当前租户全称</param>
|
|
|
|
|
/// <returns>返回生成的HTML</returns>
|
|
|
|
|
public async Task<string> GenerateSendEmailHtml(TaskBCInfo taskBCInfo, 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<BookingAttachOptions>();
|
|
|
|
|
var dirAbs = opt.basePath;
|
|
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
|
|
{
|
|
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
|
|
}
|
|
|
|
|
templatePath = $"{dirAbs}{templatePath}\\BCEmailTemplate.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.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#", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 = taskBCInfo.MBL_NO;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "takebillno-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.MBL_NO;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "pol-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.PLACERECEIPT;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "pod-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.PLACEDELIVERY;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "ctn-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.CTN_STAT;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "etd-val")
|
|
|
|
|
{
|
|
|
|
|
if (taskBCInfo.ETD.HasValue)
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.ETD.Value.ToString("yyyy-MM-dd");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "eta-val")
|
|
|
|
|
{
|
|
|
|
|
if (taskBCInfo.ETA.HasValue)
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.ETA.Value.ToString("yyyy-MM-dd");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 通过邮件模板生成HTML
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 通过邮件模板生成HTML
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskBCInfo">BC任务详情</param>
|
|
|
|
|
/// <param name="opUserInfo">订舱OP详情</param>
|
|
|
|
|
/// <param name="tenantName">当前租户全称</param>
|
|
|
|
|
/// <returns>返回生成的HTML</returns>
|
|
|
|
|
public async Task<string> GenerateSendEmailHtmlAmendment(TaskBCInfo taskBCInfo, 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<BookingAttachOptions>();
|
|
|
|
|
var dirAbs = opt.basePath;
|
|
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
|
|
{
|
|
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
|
|
}
|
|
|
|
|
templatePath = $"{dirAbs}{templatePath}\\BCModifyEmailTemplate.html";
|
|
|
|
|
|
|
|
|
|
string baseHtml = File.ReadAllText(templatePath);
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(baseHtml))
|
|
|
|
|
throw Oops.Oh($"读取邮件模板失败");
|
|
|
|
|
|
|
|
|
|
List<CompareResultDetailInfo> compareList = GetCompareResult(taskBCInfo.TASK_ID).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
if (compareList == null || compareList.Count == 0)
|
|
|
|
|
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.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#", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 = taskBCInfo.MBL_NO;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "takebillno-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.MBL_NO;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "pol-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.PLACERECEIPT;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "pod-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.PLACEDELIVERY;
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "ctn-val")
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.CTN_STAT;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "etd-val")
|
|
|
|
|
{
|
|
|
|
|
if (taskBCInfo.ETD.HasValue)
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.ETD.Value.ToString("yyyy-MM-dd");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (baseTd.Attributes["class"].Value == "eta-val")
|
|
|
|
|
{
|
|
|
|
|
if (taskBCInfo.ETA.HasValue)
|
|
|
|
|
{
|
|
|
|
|
baseTd.InnerHtml = taskBCInfo.ETA.Value.ToString("yyyy-MM-dd");
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isOnlyChangeOne = false;
|
|
|
|
|
|
|
|
|
|
List<string> nameList = new List<string>();
|
|
|
|
|
//船名
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("vessel", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("vessel", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">船名 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("船名");
|
|
|
|
|
}
|
|
|
|
|
//航次号
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("voyNo", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("voyNo", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">航次号 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("航次号");
|
|
|
|
|
}
|
|
|
|
|
//ETD
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("ETD", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("ETD", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">ETD 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("ETD");
|
|
|
|
|
}
|
|
|
|
|
//ETA
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("ETA", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("ETA", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">ETA 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("ETA");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//CustomSICutDate 客户样单截止日期
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("CustomSICutDate", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("CustomSICutDate", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">样单截止日期 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("样单截止日期");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//CYCutoffTime 截港时间
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("CYCutoffTime", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("CYCutoffTime", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">截港时间 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("截港时间");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//ManifestCutDate 舱单截止时间
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("ManifestCutDate", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("ManifestCutDate", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">舱单截止时间 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("舱单截止时间");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//VGMCutoffTime MDGF提交截止时间
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("VGMCutoffTime", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("VGMCutoffTime", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">截VGM时间 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("截VGM时间");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//MDGFCutDate MDGF提交截止时间
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("MDGFCutDate", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("MDGFCutDate", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"30%\">MDGF提交截止时间 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("MDGF提交截止时间");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//PlaceReceipt 收货地
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("PlaceReceipt", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("PlaceReceipt", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"20%\">收货地 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("收货地");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//PlaceDelivery 交货地
|
|
|
|
|
if (compareList.Any(x => x.FieldCode.Equals("PlaceDelivery", StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
{
|
|
|
|
|
var name = compareList.FirstOrDefault(x => x.FieldCode.Equals("PlaceDelivery", StringComparison.OrdinalIgnoreCase)).TargetVal;
|
|
|
|
|
|
|
|
|
|
baseTable.AppendChild(HtmlNode.CreateNode("<tr><td class=\"ctn-label\" width=\"20%\">交货地 变更为:</td><td class=\"pod-val\" width=\"160\">" + name + "</td></tr>"));
|
|
|
|
|
|
|
|
|
|
nameList.Add("交货地");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
else if(baseP.Attributes["class"].Value == "dynamic-val")
|
|
|
|
|
{
|
|
|
|
|
if (nameList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
baseP.InnerHtml = $"请注意{(string.Join("、", nameList.ToArray()))} 变更,请您按相关的更新安排操作,谢谢!";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = html.DocumentNode.OuterHtml;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"通过邮件模板生成HTML异常,原因={ex.Message}");
|
|
|
|
|
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
emailApiUserDefinedDto.Attaches.Add(new AttachesInfo
|
|
|
|
|
{
|
|
|
|
|
AttachName = Path.GetFileName(filePath).Replace("_MODIFY",""),
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
#region 发送邮件
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发送邮件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPKId">BC任务主键</param>
|
|
|
|
|
/// <param name="usePersonalEmailSend">是否默认使用用户个人邮箱发送</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/SendEmail")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> SendEmail(string taskPKId, bool usePersonalEmailSend = false)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskPKId))
|
|
|
|
|
throw Oops.Oh($"BC任务主键不能为空");
|
|
|
|
|
|
|
|
|
|
var bcTaskInfo = await _taskBaseRepository.AsQueryable().Filter(null,true).FirstAsync(u => u.PK_ID == taskPKId);
|
|
|
|
|
if (bcTaskInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcOrder = _taskBCInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == bcTaskInfo.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (bcOrder == null)
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPKId}无法获取BC业务信息");
|
|
|
|
|
|
|
|
|
|
return await GenerateSendEmail(bcOrder, bcTaskInfo);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取当前比对结果
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取当前比对结果
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPKId">BC任务主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/GetCompareResult")]
|
|
|
|
|
public async Task<List<CompareResultDetailInfo>> GetCompareResult(string taskPKId)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskPKId))
|
|
|
|
|
throw Oops.Oh($"BC任务主键不能为空");
|
|
|
|
|
|
|
|
|
|
var bcTaskInfo = await _taskBaseRepository.AsQueryable().Filter(null,true).FirstAsync(u => u.PK_ID == taskPKId);
|
|
|
|
|
if (bcTaskInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcOrder = _taskBCInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == bcTaskInfo.PK_ID);
|
|
|
|
|
|
|
|
|
|
if (bcOrder == null)
|
|
|
|
|
throw Oops.Oh($"任务主键{taskPKId}无法获取BC业务信息");
|
|
|
|
|
|
|
|
|
|
return await _bookingSlotService.GetSlotCompareResult(bcOrder.BOOKING_SLOT_ID.Value, bcOrder.BATCH_NO);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 同步舱位变更
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 同步舱位变更
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPKId">BC任务主键</param>
|
|
|
|
|
/// <param name="tenantId">租户ID</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/SyncBookingSlotChange")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> SyncBookingSlotChange(string taskPKId, long tenantId)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Amendment
|
|
|
|
|
1、需要先匹配舱位,如果没有舱位不能执行后续的步骤。
|
|
|
|
|
2、判断当前租户是否配置了自动转发客户邮件。
|
|
|
|
|
3、如果配置了自动转发,需要判断订舱是否已有,没有不能执行自动转发。
|
|
|
|
|
4、转发需要提取差异数据,如果没有差异数据也不能转发邮件。
|
|
|
|
|
5、默认通过钉钉通知操作收到了变更通知。
|
|
|
|
|
* Cancellation
|
|
|
|
|
1、需要先匹配舱位,如果没有舱位不能执行后续的步骤。
|
|
|
|
|
2、判断当前租户是否配置了自动转发客户邮件。
|
|
|
|
|
3、如果配置了自动转发,需要判断订舱是否已有,没有不能执行自动转发。
|
|
|
|
|
4、转发需要提取差异数据,如果没有差异数据也不能转发邮件。
|
|
|
|
|
*/
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var baseTask = _taskBaseRepository.AsQueryable().Filter(null, true).First(u => u.PK_ID == taskPKId && u.TenantId == tenantId);
|
|
|
|
|
if (baseTask == null)
|
|
|
|
|
throw Oops.Oh($"主任务获取失败,不存在或已作废");
|
|
|
|
|
|
|
|
|
|
var bcOrder = _taskBCInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == taskPKId && a.TenantId == tenantId);
|
|
|
|
|
|
|
|
|
|
if (bcOrder == null)
|
|
|
|
|
throw Oops.Oh($"BC任务获取失败,不存在或已作废");
|
|
|
|
|
|
|
|
|
|
if (!bcOrder.BOOKING_SLOT_ID.HasValue || bcOrder.BOOKING_SLOT_ID.Value == 0)
|
|
|
|
|
{
|
|
|
|
|
var server = _namedBookingSlotServiceProvider.GetService<ITransient>(nameof(BookingSlotService));
|
|
|
|
|
var slotModel = server.SearchBookingSlotWithOrderByNo(bcOrder.MBL_NO, bcOrder.TenantId.Value).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
if (slotModel != null && slotModel.BookingSlotId > 0)
|
|
|
|
|
{
|
|
|
|
|
if (slotModel.HasBookingOrder)
|
|
|
|
|
{
|
|
|
|
|
bcOrder.BOOKING_SLOT_ID = slotModel.BookingSlotId;
|
|
|
|
|
bcOrder.BOOKING_ORDER_ID = slotModel.BookingOrderList.FirstOrDefault();
|
|
|
|
|
bcOrder.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcOrder.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcOrder.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcOrder).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.BOOKING_ORDER_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bcOrder.BOOKING_SLOT_ID = slotModel.BookingSlotId;
|
|
|
|
|
bcOrder.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcOrder.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcOrder.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcOrder).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (baseTask != null)
|
|
|
|
|
{
|
|
|
|
|
if (baseTask.IS_PUBLIC == 1)
|
|
|
|
|
{
|
|
|
|
|
baseTask.IS_PUBLIC = 0;
|
|
|
|
|
baseTask.RealUserId = UserManager.UserId;
|
|
|
|
|
baseTask.RealUserName = UserManager.Name;
|
|
|
|
|
baseTask.UpdatedTime = DateTime.Now;
|
|
|
|
|
baseTask.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
baseTask.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
//更新任务台,将当前任务变更为个人任务
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(baseTask).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.IS_PUBLIC,
|
|
|
|
|
it.RealUserId,
|
|
|
|
|
it.RealUserName,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"无法获取舱位信息");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//去关联的订舱ID
|
|
|
|
|
if(bcOrder.BOOKING_ORDER_ID == null || bcOrder.BOOKING_ORDER_ID.Value == 0)
|
|
|
|
|
{
|
|
|
|
|
var server = _namedBookingSlotServiceProvider.GetService<ITransient>(nameof(BookingSlotService));
|
|
|
|
|
var slotModel = server.SearchBookingSlotWithOrderByNo(bcOrder.MBL_NO, bcOrder.TenantId.Value).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
if (slotModel.HasBookingOrder)
|
|
|
|
|
{
|
|
|
|
|
bcOrder.BOOKING_ORDER_ID = slotModel.BookingOrderList.FirstOrDefault();
|
|
|
|
|
bcOrder.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcOrder.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcOrder.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcOrder).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_ORDER_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DjyTenantParamValueOutput paramConfig = null;
|
|
|
|
|
DjyTenantParamValueOutput dingdingConfig = null;
|
|
|
|
|
|
|
|
|
|
var paramList = _djyTenantParamService.GetParaCodeWithValue(new[] { CONST_AMENDMENT_DEFAULT_PARAM,
|
|
|
|
|
CONST_CANCELLATION_DEFAULT_PARAM,
|
|
|
|
|
CONST_AMENDMENT_DING_DEFAULT_PARAM,
|
|
|
|
|
CONST_CANCELLATION_DING_DEFAULT_PARAM }).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
if (baseTask.TASK_TYPE == TaskBaseTypeEnum.BC_MODIFY.ToString())
|
|
|
|
|
{
|
|
|
|
|
if (paramList != null && paramList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
paramConfig = paramList.FirstOrDefault(a => a.ParaCode.Equals(CONST_AMENDMENT_DEFAULT_PARAM, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
dingdingConfig = paramList.FirstOrDefault(a => a.ParaCode.Equals(CONST_AMENDMENT_DING_DEFAULT_PARAM, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (baseTask.TASK_TYPE == TaskBaseTypeEnum.CANCELLATION.ToString())
|
|
|
|
|
{
|
|
|
|
|
if (paramList != null && paramList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
paramConfig = paramList.FirstOrDefault(a => a.ParaCode.Equals(CONST_CANCELLATION_DEFAULT_PARAM, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
dingdingConfig = paramList.FirstOrDefault(a => a.ParaCode.Equals(CONST_CANCELLATION_DING_DEFAULT_PARAM, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 判断是否默认转发邮件 paramConfig={JSON.Serialize(paramConfig)}");
|
|
|
|
|
|
|
|
|
|
//如果值是ENABLE表示可以自动发送
|
|
|
|
|
if (paramConfig != null && paramConfig.ParaValue.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 准备发送邮件");
|
|
|
|
|
|
|
|
|
|
var emailRlt = await SendEmail(taskPKId);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 发送邮件完成 结果={JSON.Serialize(emailRlt)}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 未配置自动发送邮件");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dingdingConfig != null && dingdingConfig.ParaValue.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 准备发送钉钉消息");
|
|
|
|
|
|
|
|
|
|
var emailRlt = await SendEmail(taskPKId);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 发送钉钉消息完成 结果={JSON.Serialize(emailRlt)}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"taskPKId={taskPKId} 未配置自动发送邮件");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "执行成功";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"处理异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 重试处理BC任务
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 重试处理BC任务
|
|
|
|
|
/// 对未匹配舱位、订舱订单的任务记录重新对应舱位、订舱订单
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPkId">BC任务主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/SearchAndConnectBookingInfo")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> 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}无法获取业务信息");
|
|
|
|
|
|
|
|
|
|
string mblNo = taskBCInfo.MBL_NO.ToUpper().Trim();
|
|
|
|
|
|
|
|
|
|
var server = _namedBookingSlotServiceProvider.GetService<ITransient>(nameof(BookingSlotService));
|
|
|
|
|
|
|
|
|
|
//首先检索关联舱位
|
|
|
|
|
if (!taskBCInfo.BOOKING_SLOT_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
//var server = _namedBookingSlotServiceProvider.GetService<ITransient>(nameof(BookingSlotService));
|
|
|
|
|
var slotInfo = await server.SearchBookingSlotWithOrderByNo(mblNo, taskBCInfo.TenantId.Value);
|
|
|
|
|
|
|
|
|
|
if (slotInfo == null)
|
|
|
|
|
throw Oops.Oh($"提单号{mblNo}未提取有效的舱位信息");
|
|
|
|
|
|
|
|
|
|
taskBCInfo.BOOKING_SLOT_ID = slotInfo.BookingSlotId;
|
|
|
|
|
taskBCInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskBCInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
if (slotInfo.HasBookingOrder && !taskBCInfo.BOOKING_ORDER_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
taskBCInfo.BOOKING_ORDER_ID = slotInfo.BookingOrderList.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
//更新任务BC
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(taskBCInfo).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.BOOKING_ORDER_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//更新任务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.BOOKING_ORDER_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var slotInfo = await server.SearchBookingSlotWithOrderByNo(mblNo, taskBCInfo.TenantId.Value);
|
|
|
|
|
|
|
|
|
|
if (slotInfo == null)
|
|
|
|
|
throw Oops.Oh($"提单号{mblNo}未提取有效的舱位信息");
|
|
|
|
|
|
|
|
|
|
if (slotInfo.HasBookingOrder && !taskBCInfo.BOOKING_ORDER_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
taskBCInfo.BOOKING_ORDER_ID = slotInfo.BookingOrderList.FirstOrDefault();
|
|
|
|
|
taskBCInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
taskBCInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
//更新任务BC
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(taskBCInfo).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_ORDER_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<BookingSlotCtnSaveInput>()
|
|
|
|
|
},
|
|
|
|
|
OpType = "cancellation"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"提单号{mblNo} 推送舱位取消");
|
|
|
|
|
|
|
|
|
|
var pushRlt = await server.ApiReceive(JSON.Serialize(slotModel));
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"提单号{mblNo} 推送舱位取消,结果={JSON.Serialize(pushRlt)}");
|
|
|
|
|
|
|
|
|
|
var service = _namedBookingMSKAPIServiceProvider
|
|
|
|
|
.GetService<ITransient>(nameof(BookingMSKAPIService));
|
|
|
|
|
|
|
|
|
|
var synRlt = await service.SyncBCInfo(taskBCInfo.MBL_NO, taskBCInfo.TenantId.Value, "Cancellation");
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"入库完BC,自动推送状态到API订舱列表 mblno={taskBCInfo.MBL_NO} synRlt={JSON.Serialize(synRlt)}");
|
|
|
|
|
}
|
|
|
|
|
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<BookingSlotCtnSaveInput>()
|
|
|
|
|
},
|
|
|
|
|
OpType = "update"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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<BookingAttachOptions>();
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
#region 重新比对
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 重新比对
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPKId">BC任务主键</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/ReCompareResult")]
|
|
|
|
|
public async Task ReCompareResult(string taskPKId)
|
|
|
|
|
{
|
|
|
|
|
List<CompareResultDetailInfo> list = new List<CompareResultDetailInfo>();
|
|
|
|
|
/*
|
|
|
|
|
1、判断舱位是否存在,如果舱位不存在终止重新比对。
|
|
|
|
|
2、获取BookingConfirmation任务,如果不存在终止。
|
|
|
|
|
3、调取BookingConfirmation文件识别结果,与当前任务的文件识别重新比对。
|
|
|
|
|
4、更新到对应的舱位
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
var baseTask = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPKId);
|
|
|
|
|
|
|
|
|
|
if (baseTask == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未提取有效的任务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (baseTask.TASK_TYPE != TaskBaseTypeEnum.BC_MODIFY.ToString())
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"任务类型不是Amendment不能重新比对");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcTaskInfo = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == taskPKId);
|
|
|
|
|
|
|
|
|
|
if (bcTaskInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未提取有效的BC任务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long slotId = 0;
|
|
|
|
|
string reqBatchNo = bcTaskInfo.BATCH_NO;
|
|
|
|
|
|
|
|
|
|
var server = _namedBookingSlotServiceProvider.GetService<ITransient>(nameof(BookingSlotService));
|
|
|
|
|
|
|
|
|
|
//没有舱位先要匹配舱位,才能比对
|
|
|
|
|
if (!bcTaskInfo.BOOKING_SLOT_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var searchInfo = await server.SearchBookingSlotWithOrderByNo(bcTaskInfo.MBL_NO, bcTaskInfo.TenantId.Value);
|
|
|
|
|
|
|
|
|
|
if (searchInfo != null)
|
|
|
|
|
{
|
|
|
|
|
if (searchInfo.HasBookingOrder)
|
|
|
|
|
{
|
|
|
|
|
bcTaskInfo.BOOKING_SLOT_ID = searchInfo.BookingSlotId;
|
|
|
|
|
bcTaskInfo.BOOKING_ORDER_ID = searchInfo.BookingOrderList.FirstOrDefault();
|
|
|
|
|
bcTaskInfo.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcTaskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcTaskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcTaskInfo).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.BOOKING_ORDER_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bcTaskInfo.BOOKING_SLOT_ID = searchInfo.BookingSlotId;
|
|
|
|
|
bcTaskInfo.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcTaskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcTaskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcTaskInfo).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_SLOT_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (baseTask.IS_PUBLIC == 1)
|
|
|
|
|
{
|
|
|
|
|
baseTask.IS_PUBLIC = 0;
|
|
|
|
|
baseTask.RealUserId = UserManager.UserId;
|
|
|
|
|
baseTask.RealUserName = UserManager.Name;
|
|
|
|
|
baseTask.UpdatedTime = DateTime.Now;
|
|
|
|
|
baseTask.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
baseTask.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
//更新任务台,将当前任务变更为个人任务
|
|
|
|
|
await _taskBaseRepository.AsUpdateable(baseTask).UpdateColumns(it => new {
|
|
|
|
|
it.IS_PUBLIC,
|
|
|
|
|
it.RealUserId,
|
|
|
|
|
it.RealUserName,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
slotId = bcTaskInfo.BOOKING_SLOT_ID.Value;
|
|
|
|
|
|
|
|
|
|
var bcInfo = _taskBaseRepository.AsQueryable().Filter(null, true).Where(a => a.MBL_NO == bcTaskInfo.MBL_NO && a.CARRIER_ID == bcTaskInfo.CARRIERID
|
|
|
|
|
&& a.TASK_TYPE == TaskBaseTypeEnum.BC.ToString() && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID).First();
|
|
|
|
|
|
|
|
|
|
if (bcInfo == null)
|
|
|
|
|
throw Oops.Oh($"未检索到对应的BC任务");
|
|
|
|
|
|
|
|
|
|
var modifyFile = _taskFileRepository.AsQueryable().First(a => a.TASK_PKID == taskPKId && a.FILE_CATEGORY == "BC_MODIFY");
|
|
|
|
|
|
|
|
|
|
if(modifyFile == null)
|
|
|
|
|
throw Oops.Oh($"未获取到当前任务的文件信息");
|
|
|
|
|
|
|
|
|
|
var bcFile = _taskFileRepository.AsQueryable().First(a => a.TASK_PKID == bcInfo.PK_ID && a.FILE_CATEGORY == "BC");
|
|
|
|
|
|
|
|
|
|
if (bcFile == null)
|
|
|
|
|
throw Oops.Oh($"未获取到当前任务对应BC的文件信息");
|
|
|
|
|
|
|
|
|
|
var modifyFileName = Path.GetFileName(modifyFile.FILE_PATH);
|
|
|
|
|
var bcFileName = Path.GetFileName(bcFile.FILE_PATH);
|
|
|
|
|
|
|
|
|
|
var opt = App.GetOptions<BookingAttachOptions>();
|
|
|
|
|
var dirAbs = opt.basePath;
|
|
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
|
|
{
|
|
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var modifyFileFullPath = Path.Combine(dirAbs, modifyFile.FILE_PATH);
|
|
|
|
|
if (!File.Exists(modifyFileFullPath))
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh("Amendment 文件提取失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcFileFullPath = Path.Combine(dirAbs, bcFile.FILE_PATH);
|
|
|
|
|
if (!File.Exists(bcFileFullPath))
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh("BC 文件提取失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskBCInfoReadDto modifyBCReadInfo = await GetBCReaderInfo(modifyFileFullPath, modifyFileName, UserManager.TENANT_ID, taskPKId, App.Configuration["BookingAmendReadWebApiUrl"]);
|
|
|
|
|
|
|
|
|
|
if (modifyBCReadInfo == null)
|
|
|
|
|
throw Oops.Oh($"重新读取BC变更文件详情失败");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TaskBCInfoReadDto BCReadInfo = await GetBCReaderInfo(bcFileFullPath, bcFileName, UserManager.TENANT_ID, taskPKId, App.Configuration["BCReadWebApiUrl"]);
|
|
|
|
|
|
|
|
|
|
if (BCReadInfo == null)
|
|
|
|
|
throw Oops.Oh($"重新读取BC文件详情失败");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TaskBCInfoDto bcSrcDto = BCReadInfo.Adapt<TaskBCInfoDto>();
|
|
|
|
|
TaskBCInfoDto bcTargetDto = modifyBCReadInfo.Adapt<TaskBCInfoDto>();
|
|
|
|
|
|
|
|
|
|
if (BCReadInfo.CtnList != null && BCReadInfo.CtnList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
bcSrcDto.CtnList = BCReadInfo.CtnList.GroupBy(x => x.CtnALL)
|
|
|
|
|
.Select(x =>
|
|
|
|
|
{
|
|
|
|
|
return new TaskBCCTNInfoDto
|
|
|
|
|
{
|
|
|
|
|
CtnALL = x.Key,
|
|
|
|
|
CTNNUM = x.ToList()
|
|
|
|
|
.Sum(a => a.CTNNUM)
|
|
|
|
|
};
|
|
|
|
|
}).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (modifyBCReadInfo.CtnList != null && modifyBCReadInfo.CtnList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
bcTargetDto.CtnList = modifyBCReadInfo.CtnList.GroupBy(x => x.CtnALL)
|
|
|
|
|
.Select(x =>
|
|
|
|
|
{
|
|
|
|
|
return new TaskBCCTNInfoDto
|
|
|
|
|
{
|
|
|
|
|
CtnALL = x.Key,
|
|
|
|
|
CTNNUM = x.ToList()
|
|
|
|
|
.Sum(a => a.CTNNUM)
|
|
|
|
|
};
|
|
|
|
|
}).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"触发比对差异开始,reqBatchNo={reqBatchNo}");
|
|
|
|
|
|
|
|
|
|
//比对差异
|
|
|
|
|
await server.PushCompareBCInfo(bcSrcDto, bcTargetDto, slotId, reqBatchNo);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"触发比对差异结束,reqBatchNo={reqBatchNo}");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 读BC详情详情
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 读BC详情详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="attachFullName">文件完整路径</param>
|
|
|
|
|
/// <param name="fileName">文件名称</param>
|
|
|
|
|
/// <param name="tenantId">所属租户</param>
|
|
|
|
|
/// <param name="taskPKId">任务ID</param>
|
|
|
|
|
/// <param name="url">请求URL</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task<TaskBCInfoReadDto> GetBCReaderInfo(string attachFullName, string fileName, long tenantId,string taskPKId,string url)
|
|
|
|
|
{
|
|
|
|
|
TaskBCInfoReadDto taskBCInfoReadDto = null;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
EmailBCReadMessageInfo messageInfo = new EmailBCReadMessageInfo
|
|
|
|
|
{
|
|
|
|
|
Head = new TaskMessageHead
|
|
|
|
|
{
|
|
|
|
|
GID = IDGen.NextID().ToString(),
|
|
|
|
|
MessageType = "BOOKING_AMENDMENT",
|
|
|
|
|
SenderId = "DJY",
|
|
|
|
|
SenderName = "新大简云",
|
|
|
|
|
ReceiverId = "RulesEngine",
|
|
|
|
|
ReceiverName = "大简云规则引擎",
|
|
|
|
|
Version = "1.0",
|
|
|
|
|
RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"),
|
|
|
|
|
RequestAction = "ReadFile",
|
|
|
|
|
},
|
|
|
|
|
Main = new EmailBCReadMessageMainInfo
|
|
|
|
|
{
|
|
|
|
|
TenantId = tenantId > 0 ? tenantId.ToString() : ""
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
NameValueCollection par = new NameValueCollection();
|
|
|
|
|
par.Add("jsonData", JSON.Serialize(messageInfo));
|
|
|
|
|
|
|
|
|
|
//解析BookingAmendment
|
|
|
|
|
var compareRlt = await ExcuteReadFile(par, url,new
|
|
|
|
|
{
|
|
|
|
|
file = "file",
|
|
|
|
|
fileName = fileName,
|
|
|
|
|
fileBytes = File.ReadAllBytes(attachFullName)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"读取BC附件详情 taskPKId={taskPKId},compareRlt={JSON.Serialize(compareRlt)}");
|
|
|
|
|
|
|
|
|
|
if (compareRlt.succ)
|
|
|
|
|
{
|
|
|
|
|
taskBCInfoReadDto = JSON.Deserialize<TaskBCInfoReadDto>(JSON.Serialize(compareRlt.extra));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"读取BC附件详情异常,原因:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return taskBCInfoReadDto;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 请求BookingAmendment解析
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求BookingAmendment解析
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="nameValueCollection">请求参数</param>
|
|
|
|
|
/// <param name="url">请求url</param>
|
|
|
|
|
/// <param name="fileInfo">文件</param>
|
|
|
|
|
/// <param name="contentType">请求类型</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[NonAction]
|
|
|
|
|
private async Task<ParserReaderExcuteResultDto> ExcuteReadFile(NameValueCollection nameValueCollection, string url,dynamic fileInfo,
|
|
|
|
|
string contentType = "application/json")
|
|
|
|
|
{
|
|
|
|
|
ParserReaderExcuteResultDto model = null;
|
|
|
|
|
var result = string.Empty;
|
|
|
|
|
|
|
|
|
|
using (var httpClient = new HttpClient())
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (var reduceAttach = new MultipartFormDataContent())
|
|
|
|
|
{
|
|
|
|
|
string[] allKeys = nameValueCollection.AllKeys;
|
|
|
|
|
foreach (string key in allKeys)
|
|
|
|
|
{
|
|
|
|
|
var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(nameValueCollection[key]));
|
|
|
|
|
|
|
|
|
|
dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue($"form-data")
|
|
|
|
|
{
|
|
|
|
|
Name = key
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
reduceAttach.Add(dataContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 文件参数
|
|
|
|
|
if (fileInfo != null)
|
|
|
|
|
{
|
|
|
|
|
var Content = new ByteArrayContent(fileInfo.fileBytes);
|
|
|
|
|
|
|
|
|
|
//Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
|
|
|
|
|
//{
|
|
|
|
|
// Name = fileInfo.file.ToString(),
|
|
|
|
|
// FileName = fileInfo.fileName.ToString(),
|
|
|
|
|
|
|
|
|
|
//};
|
|
|
|
|
|
|
|
|
|
Content.Headers.Add("Content-Type", contentType);
|
|
|
|
|
|
|
|
|
|
reduceAttach.Add(Content, fileInfo.file.ToString(), HttpUtility.UrlEncode(fileInfo.fileName.ToString()));
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
//httpClient.DefaultRequestHeaders.Add("USER_KEY", App.Configuration["ApiUserKey"]);
|
|
|
|
|
//httpClient.DefaultRequestHeaders.Add("USER_SECRET", App.Configuration["ApiUserSecret"]);
|
|
|
|
|
//请求
|
|
|
|
|
var response = httpClient.PostAsync(url, reduceAttach).Result;
|
|
|
|
|
result = response.Content.ReadAsStringAsync().Result;
|
|
|
|
|
|
|
|
|
|
model = JSON.Deserialize<ParserReaderExcuteResultDto>(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("请求读取BC附件详情读取详情异常,原因:{error}", ex.Message);
|
|
|
|
|
|
|
|
|
|
throw Oops.Oh($"请求读取BC附件详情读取详情异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取BC关联的订舱详情
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取BC关联的订舱详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskPkId">BC任务主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageBC/GetBookingOrder")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> GetBookingOrder(string taskPkId)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
var baseTask = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId);
|
|
|
|
|
|
|
|
|
|
if (baseTask == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未提取有效的任务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bcTaskInfo = _taskBCInfoRepository.AsQueryable().First(a => a.TASK_ID == taskPkId);
|
|
|
|
|
|
|
|
|
|
if (bcTaskInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"未提取有效的BC任务信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!bcTaskInfo.BOOKING_ORDER_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var server = _namedBookingSlotServiceProvider.GetService<ITransient>(nameof(BookingSlotService));
|
|
|
|
|
|
|
|
|
|
var slotModel = server.SearchBookingSlotWithOrderByNo(bcTaskInfo.MBL_NO, bcTaskInfo.TenantId.Value).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
if (slotModel != null && slotModel.BookingSlotId > 0)
|
|
|
|
|
{
|
|
|
|
|
if (slotModel.HasBookingOrder)
|
|
|
|
|
{
|
|
|
|
|
bcTaskInfo.BOOKING_ORDER_ID = slotModel.BookingOrderList.FirstOrDefault();
|
|
|
|
|
bcTaskInfo.UpdatedTime = DateTime.Now;
|
|
|
|
|
bcTaskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bcTaskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskBCInfoRepository.AsUpdateable(bcTaskInfo).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.BOOKING_ORDER_ID,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bcTaskInfo.BOOKING_ORDER_ID.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var bkRlt = await _bookingOrderService.Get(bcTaskInfo.BOOKING_ORDER_ID.Value);
|
|
|
|
|
|
|
|
|
|
if (bkRlt != null)
|
|
|
|
|
{
|
|
|
|
|
var BookingSubmitResultModel = new BookingOrSlotGenerateDto
|
|
|
|
|
{
|
|
|
|
|
CustomerId = bkRlt.CUSTOMERID,
|
|
|
|
|
CustomerName = bkRlt.CUSTOMERNAME,
|
|
|
|
|
CustServiceId = !string.IsNullOrWhiteSpace(bkRlt.CUSTSERVICEID)? long.Parse(bkRlt.CUSTSERVICEID):null,
|
|
|
|
|
CustServiceName = bkRlt.CUSTSERVICE,
|
|
|
|
|
SaleId = !string.IsNullOrWhiteSpace(bkRlt.SALEID) ? long.Parse(bkRlt.SALEID) : null,
|
|
|
|
|
SaleName = bkRlt.SALE,
|
|
|
|
|
OpId = !string.IsNullOrWhiteSpace(bkRlt.OPID) ? long.Parse(bkRlt.OPID) : null,
|
|
|
|
|
OpName = bkRlt.OP,
|
|
|
|
|
DocId = !string.IsNullOrWhiteSpace(bkRlt.DOCID) ? long.Parse(bkRlt.DOCID) : null,
|
|
|
|
|
DocName = bkRlt.DOC,
|
|
|
|
|
RouteID = !string.IsNullOrWhiteSpace(bkRlt.ROUTEID) ? long.Parse(bkRlt.ROUTEID) : null,
|
|
|
|
|
Route = bkRlt.ROUTE,
|
|
|
|
|
LineManageID = !string.IsNullOrWhiteSpace(bkRlt.LineManageID) ? long.Parse(bkRlt.LineManageID) : null,
|
|
|
|
|
LineManage = bkRlt.LineManage
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result.ext = BookingSubmitResultModel;
|
|
|
|
|
result.succ = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 更新订舱
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 更新订舱
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskBCInfo">BC任务详情</param>
|
|
|
|
|
/// <param name="taskBCCtnList">BC任务集装箱列表</param>
|
|
|
|
|
/// <param name="taskFileList">BC任务附件列表</param>
|
|
|
|
|
/// <param name="generateModel">订舱请求详情</param>
|
|
|
|
|
/// <returns>返回订舱ID</returns>
|
|
|
|
|
private async Task<long> UpdateBookingOrder(TaskBCInfo taskBCInfo, List<TaskBCCTNInfo> taskBCCtnList, List<TaskFileInfo> taskFileList,
|
|
|
|
|
BookingOrSlotGenerateDto generateModel)
|
|
|
|
|
{
|
|
|
|
|
long id = 0;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
1、新增订舱
|
|
|
|
|
2、推送服务项目
|
|
|
|
|
3、推送附件
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
var carrierInfo = _cache.GetAllCodeCarrier().GetAwaiter().GetResult()
|
|
|
|
|
.Where(t => t.Code.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|| t.EnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|| t.CnName.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
SaveBookingOrderInput bkModel = new SaveBookingOrderInput
|
|
|
|
|
{
|
|
|
|
|
Id = taskBCInfo.BOOKING_ORDER_ID.Value,
|
|
|
|
|
CUSTOMERID = generateModel.CustomerId,
|
|
|
|
|
CUSTOMERNAME = generateModel.CustomerName,
|
|
|
|
|
CARRIERID = carrierInfo.Code?.Trim(),
|
|
|
|
|
CARRIER = carrierInfo.CnName?.Trim(),
|
|
|
|
|
MBLNO = taskBCInfo.MBL_NO.ToUpper().Trim(),
|
|
|
|
|
CONTRACTNO = !string.IsNullOrWhiteSpace(taskBCInfo.CONTRACTNO) ? taskBCInfo.CONTRACTNO : "",
|
|
|
|
|
VESSEL = taskBCInfo.VESSEL.ToUpper().Trim(),
|
|
|
|
|
VOYNO = taskBCInfo.VOYNO.ToUpper().Trim(),
|
|
|
|
|
VOYNOINNER = taskBCInfo.VOYNO.ToUpper().Trim(),
|
|
|
|
|
ETD = taskBCInfo.ETD,
|
|
|
|
|
ETA = taskBCInfo.ETA,
|
|
|
|
|
SALEID = generateModel.SaleId.ToString(),
|
|
|
|
|
SALE = generateModel.SaleName,
|
|
|
|
|
OPID = generateModel.OpId.ToString(),
|
|
|
|
|
OP = generateModel.OpName,
|
|
|
|
|
DOCID = generateModel.DocId.ToString(),
|
|
|
|
|
DOC = generateModel.DocName,
|
|
|
|
|
ROUTEID = generateModel.RouteID.ToString(),
|
|
|
|
|
ROUTE = generateModel.Route,
|
|
|
|
|
CZRemark = generateModel.CZRemark,
|
|
|
|
|
ShenQingXiangShi = generateModel.ShenQingXiangShi,
|
|
|
|
|
LineManageID = generateModel.LineManageID.ToString(),
|
|
|
|
|
LineName = generateModel.LineManage,
|
|
|
|
|
CLOSEVGMDATE = taskBCInfo.VGM_CUTOFF_TIME,
|
|
|
|
|
CLOSINGDATE = taskBCInfo.CY_CUTOFF_TIME,
|
|
|
|
|
CLOSEDOCDATE = taskBCInfo.CUT_SINGLE_TIME,
|
|
|
|
|
CUSTSERVICEID = generateModel.CustServiceId.HasValue ? generateModel.CustServiceId.Value.ToString() : null,
|
|
|
|
|
CUSTSERVICE = generateModel.CustServiceName,
|
|
|
|
|
|
|
|
|
|
ctnInputs = new List<BookingCtnDto>()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
|
|
|
|
|
|
|
|
|
|
if (taskBCCtnList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
taskBCCtnList.ForEach(t =>
|
|
|
|
|
{
|
|
|
|
|
var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
|
|
|
|
|
a.Name.Equals(t.CTNALL, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
BookingCtnDto ctn = new BookingCtnDto
|
|
|
|
|
{
|
|
|
|
|
CTNCODE = ctnCode?.Code,
|
|
|
|
|
CTNALL = t.CTNALL,
|
|
|
|
|
CTNNUM = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bkModel.ctnInputs.Add(ctn);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bkModel.ChangedFields = new List<string>
|
|
|
|
|
{
|
|
|
|
|
nameof(SaveBookingOrderInput.CUSTOMERID),
|
|
|
|
|
nameof(SaveBookingOrderInput.CUSTOMERNAME),
|
|
|
|
|
nameof(SaveBookingOrderInput.CARRIERID),
|
|
|
|
|
nameof(SaveBookingOrderInput.CARRIER),
|
|
|
|
|
nameof(SaveBookingOrderInput.CONTRACTNO),
|
|
|
|
|
nameof(SaveBookingOrderInput.VESSEL),
|
|
|
|
|
nameof(SaveBookingOrderInput.VOYNO),
|
|
|
|
|
nameof(SaveBookingOrderInput.SALEID),
|
|
|
|
|
nameof(SaveBookingOrderInput.SALE),
|
|
|
|
|
nameof(SaveBookingOrderInput.OPID),
|
|
|
|
|
nameof(SaveBookingOrderInput.OP),
|
|
|
|
|
nameof(SaveBookingOrderInput.DOCID),
|
|
|
|
|
nameof(SaveBookingOrderInput.DOC),
|
|
|
|
|
nameof(SaveBookingOrderInput.ROUTEID),
|
|
|
|
|
nameof(SaveBookingOrderInput.ROUTE),
|
|
|
|
|
nameof(SaveBookingOrderInput.LineManageID),
|
|
|
|
|
nameof(SaveBookingOrderInput.LineName),
|
|
|
|
|
nameof(SaveBookingOrderInput.VOYNOINNER),
|
|
|
|
|
nameof(SaveBookingOrderInput.ROUTE),
|
|
|
|
|
nameof(SaveBookingOrderInput.ETD),
|
|
|
|
|
nameof(SaveBookingOrderInput.ETA),
|
|
|
|
|
nameof(SaveBookingOrderInput.CZRemark),
|
|
|
|
|
nameof(SaveBookingOrderInput.ShenQingXiangShi),
|
|
|
|
|
nameof(SaveBookingOrderInput.CLOSEVGMDATE),
|
|
|
|
|
nameof(SaveBookingOrderInput.CLOSINGDATE),
|
|
|
|
|
nameof(SaveBookingOrderInput.CUSTSERVICEID),
|
|
|
|
|
nameof(SaveBookingOrderInput.CUSTSERVICE),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var bkRlt = await _bookingOrderService.Save(bkModel);
|
|
|
|
|
|
|
|
|
|
id = bkRlt.Id;
|
|
|
|
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
|
|
|
|
if (id > 0)
|
|
|
|
|
{
|
|
|
|
|
var hisList = _bookingOrderContactRepository.AsQueryable().Where(a => a.BookingId == id && a.IsDeleted == false).ToList();
|
|
|
|
|
|
|
|
|
|
if (hisList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
//批量作废
|
|
|
|
|
hisList.ForEach(async a =>
|
|
|
|
|
{
|
|
|
|
|
a.IsDeleted = true;
|
|
|
|
|
a.UpdatedTime = DateTime.Now;
|
|
|
|
|
a.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
a.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _bookingOrderContactRepository.UpdateAsync(a);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//这里如果指定了委托单位的邮件联系人,则推送订舱联系人
|
|
|
|
|
if (generateModel.CustomerContactList != null && generateModel.CustomerContactList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var bookingContactList = _bookingOrderContactRepository.AsQueryable()
|
|
|
|
|
.Where(a => a.BookingId == id && !a.IsDeleted).ToList();
|
|
|
|
|
|
|
|
|
|
var djyCustomerInfo = _djyCustomerService.Detail(new GetDjyCustomerInput { Id = generateModel.CustomerId.Value })
|
|
|
|
|
.GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
generateModel.CustomerContactList.ForEach(contact =>
|
|
|
|
|
{
|
|
|
|
|
DjyCustomerContactOutput djyCustomerContactMan = null;
|
|
|
|
|
|
|
|
|
|
if (djyCustomerInfo.Contacts != null && djyCustomerInfo.Contacts.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
djyCustomerContactMan = djyCustomerInfo.Contacts.FirstOrDefault(a =>
|
|
|
|
|
a.Id == contact.CustomerContactId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (djyCustomerContactMan != null)
|
|
|
|
|
{
|
|
|
|
|
var bookingContact = bookingContactList
|
|
|
|
|
.FirstOrDefault(x => x.Email.Equals(djyCustomerContactMan.Email, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
if (bookingContact == null)
|
|
|
|
|
{
|
|
|
|
|
bookingContact = new BookingOrderContact
|
|
|
|
|
{
|
|
|
|
|
Name = djyCustomerContactMan.Name,
|
|
|
|
|
BookingId = id,
|
|
|
|
|
Email = djyCustomerContactMan.Email,
|
|
|
|
|
Remark = djyCustomerContactMan.Remark,
|
|
|
|
|
CreatedTime = DateTime.Now,
|
|
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
|
|
CreatedUserName = UserManager.Name
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_bookingOrderContactRepository.Insert(bookingContact);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bookingContact.Name = djyCustomerContactMan.Name;
|
|
|
|
|
bookingContact.Email = djyCustomerContactMan.Email;
|
|
|
|
|
bookingContact.Remark = djyCustomerContactMan.Remark;
|
|
|
|
|
bookingContact.UpdatedTime = DateTime.Now;
|
|
|
|
|
bookingContact.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
bookingContact.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
_bookingOrderContactRepository.AsUpdateable(bookingContact).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.Name,
|
|
|
|
|
it.Email,
|
|
|
|
|
it.Remark,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
|
|
|
|
|
}).ExecuteCommand();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (generateModel.ProjectList != null && generateModel.ProjectList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
ModifyServiceProjectDto projectDto = new ModifyServiceProjectDto
|
|
|
|
|
{
|
|
|
|
|
BookingId = id,
|
|
|
|
|
ProjectCodes = generateModel.ProjectList.Distinct().ToArray(),
|
|
|
|
|
};
|
|
|
|
|
//写入服务项目
|
|
|
|
|
var prjRlt = await _bookingValueAddedService.SaveServiceProject(projectDto);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"推送订舱的服务项目完成 id={id} rlt={JSON.Serialize(prjRlt)}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成订舱成功 id={id}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成订舱异常,原因:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 自定义邮件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class EmailApiUserDefinedDto
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 接收邮箱
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string SendTo { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 抄送
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string CCTo { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 邮件标题
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Title { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 邮件正文
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Body { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 账号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Account { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 密码(126邮箱需要在网站生成密文)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Password { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// SMTP服务器
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Server { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// SMTP端口
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int Port { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发件SSL
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool UseSSL { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 附件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<AttachesInfo> Attaches { get; set; }
|
|
|
|
|
}
|
|
|
|
|
}
|