using Furion; using Furion.DistributedIDGenerator; using Furion.DynamicApiController; using Furion.FriendlyException; using Furion.JsonSerialization; using Mapster; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Myshipping.Application.ConfigOption; using Myshipping.Application.Entity; using Myshipping.Application.Enum; using Myshipping.Application.Service.BookingSlot.Dto; using Myshipping.Core; using Myshipping.Core.Entity; using Myshipping.Core.Service; using Npoi.Mapper; using NPOI.SS.Formula.Functions; using RabbitMQ.Client; using SqlSugar; using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using Yitter.IdGenerator; namespace Myshipping.Application { /// /// BC任务 /// [ApiDescriptionSettings("Application", Name = "TaskManageBC", Order = 10)] public class TaskManageBCService: ITaskManageBCService, IDynamicApiController { private readonly ISysCacheService _cache; private readonly ILogger _logger; private readonly SqlSugarRepository _taskBCInfoRepository; private readonly SqlSugarRepository _taskBCCTNInfoRepository; private readonly SqlSugarRepository _taskBaseRepository; private readonly SqlSugarRepository _taskFileRepository; private readonly SqlSugarRepository _bookingOrderRepository; private readonly SqlSugarRepository _bookingCtnRepository; private readonly SqlSugarRepository _sysUserRepository; private readonly SqlSugarRepository _bookingFileRepository; private readonly IServiceWorkFlowBaseService _serviceWorkFlowBaseService; private readonly IBookingOrderService _bookingOrderService; private readonly IBookingSlotService _bookingSlotService; private readonly IBookingValueAddedService _bookingValueAddedService; 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"; public TaskManageBCService(SqlSugarRepository taskBCInfoRepository, SqlSugarRepository taskBaseRepository, SqlSugarRepository taskBCCTNInfoRepository, SqlSugarRepository taskFileRepository, SqlSugarRepository bookingOrderRepository, SqlSugarRepository bookingCtnRepository, SqlSugarRepository sysUserRepository, SqlSugarRepository bookingFileRepository, IServiceWorkFlowBaseService serviceWorkFlowBaseService, IBookingOrderService bookingOrderService, IBookingSlotService bookingSlotService, ISysCacheService cache, IBookingValueAddedService bookingValueAddedService) { _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; } #region 获取BC详情 /// /// 获取BC详情 /// /// BC主键 /// 返回回执 [HttpGet("/TaskManageBC/GetInfo")] public async Task GetInfo(string pkId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var bcOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == pkId); if (bcOrder == null) throw Oops.Oh($"BC主键{pkId}无法获取业务信息"); var BCCtnList = _taskBCCTNInfoRepository.AsQueryable().Where(a => a.P_ID == pkId).ToList(); TaskBCShowBaseDto model = bcOrder.Adapt(); if (BCCtnList.Count > 0) model.CtnList = BCCtnList.Adapt>(); var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToList(); if (fileList.Count > 0) model.FileList = fileList.Adapt>(); 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(); var ctnList = await _bookingCtnRepository.AsQueryable(). Where(a => a.BILLID == bkOrder.Id).ToListAsync(); if (ctnList.Count > 0) showBKOrder.ctnInputs = ctnList.Adapt>(); result.ext2 = showBKOrder; } } } catch (Exception ex) { result.succ = false; result.msg = $"获取BC详情异常,原因:{ex.Message}"; } return result; } #endregion #region 通过任务主键获取BC详情 /// /// 通过任务主键获取BC详情 /// /// BC任务主键 /// 返回回执 [HttpGet("/TaskManageBC/GetInfoByTaskId")] public async Task 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(); if (bcCtnList.Count > 0) model.CtnList = bcCtnList.Adapt>(); var fileList = _taskFileRepository.AsQueryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToList(); if (fileList.Count > 0) model.FileList = fileList.Adapt>(); model.taskStatus = taskBase.STATUS; //生成关键信息 #region 生成关键信息 model.Keywords = new List(); 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(); var ctnList = await _bookingCtnRepository.AsQueryable(). Where(a => a.BILLID == bkOrder.Id).ToListAsync(); if (ctnList.Count > 0) showBKOrder.ctnInputs = ctnList.Adapt>(); result.ext2 = showBKOrder; } } } catch (Exception ex) { result.succ = false; result.msg = $"获取BC详情异常,原因:{ex.Message}"; } return result; } #endregion #region 获取待处理的BC任务 /// /// 获取待处理的BC任务(来自邮件解析需要对应订舱,系统会根据用户的订舱台账预配) /// /// 返回回执 [HttpGet("/TaskManageBC/GetToDoBCList")] public async Task GetToDoBCList() { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); /* 1、优先匹配提单号一致的 2、判断船名航次一致的 */ try { Dictionary> toDoListDict = new Dictionary>(); //获取所有待处理的BC任务 var taskList = await _taskBCInfoRepository.AsQueryable().InnerJoin((a,b)=>a.TASK_ID == b.PK_ID) .Where((a, b)=> !a.BOOKING_ORDER_ID.HasValue && b.STATUS == TaskStatusEnum.Create.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()); } }); } //这里最后清洗一下对应的订舱数据,只保留一条符合的数据 if (toDoListDict.Count > 0) { List> tupList = new List>(); int num = 1; int odNum = 1; foreach (var kvp in toDoListDict) { var bcInfo = taskList.FirstOrDefault(a => a.BC.PK_ID == kvp.Key).BC.Adapt(); 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(); bookingOrder.Indx = odNum; bookingOrder.BCIndx = num; bcInfo.BKOrderIndx = odNum; odNum++; tupList.Add(new Tuple( bcInfo, bookingOrder )); } else { tupList.Add(new Tuple( 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下载附件 /// /// 任务ID下载附件 /// /// BC任务主键 /// 附件分类代码 /// 返回数据流 [HttpGet("/TaskManageBC/DownloadFile")] public async Task 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(); 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 检索订舱信息 /// /// 检索订舱信息 /// /// 检索条件 /// 返回回执 [HttpPost("/TaskManageBC/QueryBookingOrderList")] public async Task 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>(); result.succ = true; result.ext = bkList; } catch (Exception ex) { result.succ = false; result.msg = $"查询失败,原因:{ex.Message}"; } return result; } #endregion #region 转移任务(将任务指定给其他人) /// /// 转移任务(将任务指定给其他人) /// /// BC任务主键 /// 用户ID /// 返回回执 [HttpGet("/TaskManageBC/TransferTask")] public async Task 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 生成订舱或舱位 /// /// 生成订舱或舱位 /// /// 生成订舱或者舱位请求 /// 返回回执 [HttpPost("/TaskManageBC/CreateBookingAndSlot")] public async Task 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 ((bcOrder.BOOKING_ORDER_ID.HasValue && bcOrder.BOOKING_ORDER_ID.Value>0) || (bcOrder.BOOKING_SLOT_ID.HasValue && bcOrder.BOOKING_SLOT_ID.Value > 0)) { throw Oops.Oh($"当前BC任务已生成订舱或舱位,不能重复生成"); } if (model.GenerateMethod == "GEN_BOOKING_SLOT") { #region 推送舱位、推送订舱 //推送舱位 var bookingSlotId = GenerateBookingSlot(bcOrder, bcCtnList, fileList).GetAwaiter().GetResult(); //推送订舱 var bookingOrderId = GenerateBookingOrder(bcOrder, bcCtnList, fileList, model).GetAwaiter().GetResult(); if (bookingSlotId > 0 || bookingOrderId > 0) { var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcTaskInfo.PK_ID); if (bcEntity != null) { if (bookingOrderId > 0) bcEntity.BOOKING_ORDER_ID = bookingOrderId; if (bookingSlotId > 0) bcEntity.BOOKING_SLOT_ID = bookingSlotId; bcEntity.UpdatedTime = DateTime.Now; bcEntity.UpdatedUserId = UserManager.UserId; bcEntity.UpdatedUserName = UserManager.Name; _taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new { it.BOOKING_ORDER_ID, it.BOOKING_SLOT_ID, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommand(); var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID); if(taskEntity != null && taskEntity.IS_PUBLIC == 1) { taskEntity.IS_PUBLIC = 0; taskEntity.CreatedUserId = UserManager.UserId; taskEntity.CreatedUserName = UserManager.Name; taskEntity.UpdatedTime = DateTime.Now; taskEntity.UpdatedUserId = UserManager.UserId; taskEntity.UpdatedUserName = UserManager.Name; _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new { it.IS_PUBLIC, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName, it.CreatedUserId, it.CreatedUserName }).ExecuteCommand(); } } } #endregion } else if (model.GenerateMethod == "GEN_BOOKING") { #region 推送订舱 //推送订舱 var bookingOrderId = GenerateBookingOrder(bcOrder, bcCtnList, fileList, model).GetAwaiter().GetResult(); if (bookingOrderId > 0) { var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcTaskInfo.PK_ID); if (bcEntity != null) { if (bookingOrderId > 0) bcEntity.BOOKING_ORDER_ID = bookingOrderId; bcEntity.UpdatedTime = DateTime.Now; bcEntity.UpdatedUserId = UserManager.UserId; bcEntity.UpdatedUserName = UserManager.Name; _taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new { it.BOOKING_ORDER_ID, it.BOOKING_SLOT_ID, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommand(); var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID); if (taskEntity != null && taskEntity.IS_PUBLIC == 1) { taskEntity.IS_PUBLIC = 0; taskEntity.CreatedUserId = UserManager.UserId; taskEntity.CreatedUserName = UserManager.Name; taskEntity.UpdatedTime = DateTime.Now; taskEntity.UpdatedUserId = UserManager.UserId; taskEntity.UpdatedUserName = UserManager.Name; _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new { it.IS_PUBLIC, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName, it.CreatedUserId, it.CreatedUserName }).ExecuteCommand(); } } } #endregion } else if (model.GenerateMethod == "GEN_BOOKING_SLOT") { #region 推送舱位 //推送舱位 var bookingSlotId = GenerateBookingSlot(bcOrder, bcCtnList, fileList).GetAwaiter().GetResult(); if (bookingSlotId > 0) { var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcTaskInfo.PK_ID); if (bcEntity != null) { if (bookingSlotId > 0) bcEntity.BOOKING_SLOT_ID = bookingSlotId; bcEntity.UpdatedTime = DateTime.Now; bcEntity.UpdatedUserId = UserManager.UserId; bcEntity.UpdatedUserName = UserManager.Name; _taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new { it.BOOKING_ORDER_ID, it.BOOKING_SLOT_ID, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommand(); var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID); if (taskEntity != null && taskEntity.IS_PUBLIC == 1) { taskEntity.IS_PUBLIC = 0; taskEntity.CreatedUserId = UserManager.UserId; taskEntity.CreatedUserName = UserManager.Name; taskEntity.UpdatedTime = DateTime.Now; taskEntity.UpdatedUserId = UserManager.UserId; taskEntity.UpdatedUserName = UserManager.Name; _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new { it.IS_PUBLIC, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName, it.CreatedUserId, it.CreatedUserName }).ExecuteCommand(); } } } #endregion } result.succ = true; result.msg = "成功"; } catch (Exception ex) { result.succ = false; result.msg = $"生成订舱或舱位失败,原因:{ex.Message}"; } return result; } #endregion #region 生成舱位 /// /// 生成舱位 /// /// BC任务详情 /// BC任务集装箱列表 /// BC任务附件列表 /// 返回舱位ID private async Task GenerateBookingSlot(TaskBCInfo taskBCInfo, List taskBCCtnList, List taskFileList) { 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() }, OpType = "add" }; 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); }); } id = await _bookingSlotService.ApiReceive(slotModel); string batchNo = IDGen.NextID().ToString(); //成功后写入附件 if (id > 0) { var opt = App.GetOptions(); 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, "bcfiles", 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(); } } }); } } catch (Exception ex) { _logger.LogError($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成舱位异常,原因:{ex.Message}"); } return id; } #endregion #region 生成订舱 /// /// 生成订舱 /// /// BC任务详情 /// BC任务集装箱列表 /// BC任务附件列表 /// 订舱请求详情 /// 返回订舱ID private async Task GenerateBookingOrder(TaskBCInfo taskBCInfo, List taskBCCtnList, List 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, ctnInputs = new List() }; 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.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(); 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).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").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 取消任务 /// /// 取消任务 /// /// BC任务主键 /// 返回回执 [HttpGet("/TaskManageBC/CancelTask")] public async Task 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 获取服务项目列表 /// /// 获取服务项目列表 /// /// 返回回执 [HttpGet("/TaskManageBC/GetProjectList")] public async Task> GetProjectList() { List list = new List(); return await _serviceWorkFlowBaseService.GetEnableProjectList(UserManager.TENANT_ID.ToString()); } #endregion #region 异步写入附件表 /// /// 异步写入附件表 /// /// 订舱ID /// 文件路径 /// 文件名 /// 租户ID /// 附件类型代码 /// 附件类型名称 /// 附件模块代码 /// [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 } }