using Furion; using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Furion.DynamicApiController; using Furion.FriendlyException; using Furion.JsonSerialization; using Furion.RemoteRequest.Extensions; using Mapster; using MathNet.Numerics.LinearAlgebra.Factorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Myshipping.Application.ConfigOption; using Myshipping.Application.Entity; using Myshipping.Application.Enum; using Myshipping.Application.Helper; using Myshipping.Core; using Myshipping.Core.Entity; using Myshipping.Core.Helper; using Myshipping.Core.Service; using MySqlX.XDevAPI.Common; using NetTaste; using Newtonsoft.Json.Linq; using NPOI.HSSF.UserModel; using NPOI.OpenXmlFormats.Wordprocessing; using NPOI.SS.Formula.Functions; using Org.BouncyCastle.Crypto; using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; namespace Myshipping.Application { /// /// 派车服务 /// [ApiDescriptionSettings("Application", Name = "BookingTruck", Order = 9)] public class BookingTruckService : IBookingTruckService, IDynamicApiController, ITransient { private readonly ISysCacheService _cache; private readonly ILogger _logger; private readonly SqlSugarRepository _bookingTruckRepository; private readonly SqlSugarRepository _bookingTruckContaRepository; private readonly SqlSugarRepository _bookingOrderRepository; private readonly SqlSugarRepository _bookingCtnRepository; private readonly SqlSugarRepository _bookingPrintTemplateRepository; private readonly SqlSugarRepository _djyUserConfigConfig; private readonly SqlSugarRepository _bookingExcelTemplateRepository; private readonly SqlSugarRepository _sysUserRepository; private readonly ITaskManageExternalService _taskManageExternalService; private readonly ISysUserService _sysUserService; private readonly IDjyCustomerService _djyCustomerService; private readonly IBookingOrderService _bookingOrderService; const string PRINT_LIST_TYPE_KEY = "booking_truck_print_list"; const string PRINT_DATASOURCE_KEY = "booking_order"; const string MQ_EXCHANGE_NAME = "djy.output.booktruck.ds6"; const string MQ_QUEUE_NAME = "djy.output.booktruck.ds6"; public BookingTruckService(ISysCacheService cache, ILogger logger, SqlSugarRepository bookingTruckRepository, SqlSugarRepository bookingTruckContaRepository, SqlSugarRepository bookingOrderRepository, SqlSugarRepository bookingCtnRepository, SqlSugarRepository bookingPrintTemplateTemplate, SqlSugarRepository djyUserConfigConfig, SqlSugarRepository bookingExcelTemplateRepository, SqlSugarRepository sysUserRepository, ISysUserService sysUserService, IDjyCustomerService djyCustomerService, IBookingOrderService bookingOrderService, ITaskManageExternalService taskManageExternalService) { _cache = cache; _logger = logger; _bookingTruckRepository = bookingTruckRepository; _bookingTruckContaRepository = bookingTruckContaRepository; _bookingOrderRepository = bookingOrderRepository; _bookingCtnRepository = bookingCtnRepository; _taskManageExternalService = taskManageExternalService; _bookingPrintTemplateRepository = bookingPrintTemplateTemplate; _djyUserConfigConfig = djyUserConfigConfig; _bookingExcelTemplateRepository = bookingExcelTemplateRepository; _sysUserRepository = sysUserRepository; _sysUserService = sysUserService; _djyCustomerService = djyCustomerService; _bookingOrderService = bookingOrderService; } /// /// 保存派车 /// /// 派车信息 /// 返回回执 [HttpPost("/BookingTruck/Save")] public async Task Save(BookingTruckDto info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var id = await InnerSave(info); result.succ = true; result.msg = "保存成功"; result.ext = id; } catch (Exception ex) { result.succ = false; result.msg = $"保存派车异常,原因:{ex.Message}"; } return result; } /// /// 保存内部方法 /// /// 派车信息 /// 是否回写 /// 返回派车Id [SqlSugarUnitOfWork] private async Task InnerSave(BookingTruckDto info, bool isCallBack = false) { BookingTruck entity = info.Adapt(); if (entity == null) throw Oops.Oh($"派车信息不能为空", typeof(InvalidOperationException)); List entityCtnList = info.ContaList.Adapt>(); if (entityCtnList != null && entityCtnList.Count > 0) { //保存时默认统计箱型箱量 entity.CntrTotal = string.Join(";", entityCtnList.GroupBy(a => a.CTNALL) .Select(a => { return $"{a.Key}*{a.ToList().Sum(b => b.CTNNUM.HasValue ? b.CTNNUM.Value : 1)}"; }).ToArray()); } if (entity.DispatcherId.HasValue && entity.DispatcherId.Value > 0) { var dispatchUser = _sysUserRepository.AsQueryable().First(a => a.Id == entity.DispatcherId.Value); if (dispatchUser != null) entity.DispatcherName = dispatchUser.Name; } if (entity.Id == 0 && !isCallBack) { entity.Status = BookingTruckStatus.TEMP.ToString(); _bookingTruckRepository.Insert(entity); if (entityCtnList != null && entityCtnList.Count > 0) { entityCtnList.ForEach(async ctn => { ctn.TruckId = entity.Id; await _bookingTruckContaRepository.InsertAsync(ctn); }); } } else { var model = _bookingTruckRepository.AsQueryable().First(a => a.Id == entity.Id); if (model == null) throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException)); if (!isCallBack) { //校验 ValidateTruck(OperateTypeEnum.Save, new BookingTruck[] { model }); entity.UpdatedTime = DateTime.Now; entity.UpdatedUserId = UserManager.UserId; entity.UpdatedUserName = UserManager.Name; await _bookingTruckRepository.AsUpdateable(entity).IgnoreColumns(it => new { it.TenantId, it.CreatedTime, it.CreatedUserId, it.CreatedUserName, it.IsDeleted, it.BookingId, it.TruckId, it.TruckName, it.TruckCode, it.Status, it.TruckFlowNo, it.TaskNo }).ExecuteCommandAsync(); } else { ValidateTruck(OperateTypeEnum.DispatchBackSave, new BookingTruck[] { model }); entity.UpdatedTime = DateTime.Now; entity.UpdatedUserId = UserManager.UserId; entity.UpdatedUserName = UserManager.Name; entity.Status = info.CallBackStatus; await _bookingTruckRepository.AsUpdateable(entity).IgnoreColumns(it => new { it.TenantId, it.CreatedTime, it.CreatedUserId, it.CreatedUserName, it.IsDeleted, it.BookingId, it.TruckFlowNo, it.TaskNo }).ExecuteCommandAsync(); } await _bookingTruckContaRepository.DeleteAsync(x => x.TruckId == model.Id); if (entityCtnList != null && entityCtnList.Count > 0) { entityCtnList.ForEach(async ctn => { ctn.TruckId = entity.Id; await _bookingTruckContaRepository.InsertAsync(ctn); }); } } return entity.Id; } /// /// 获取派车详情 /// /// 派车主键 /// 返回回执 [HttpGet("/BookingTruck/GetInfo")] public async Task GetInfo(long id) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var truckOrder = _bookingTruckRepository.AsQueryable().First(a => a.Id == id); if (truckOrder == null) throw Oops.Oh($"派车主键{id}无法获取业务信息"); var truckCtnList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == id).ToList(); BookingTruckShowDto model = truckOrder.Adapt(); if (truckCtnList.Count > 0) model.ContaList = truckCtnList.Adapt>(); result.succ = true; result.ext = model; } catch (Exception ex) { result.succ = false; result.msg = $"获取派车详情异常,原因:{ex.Message}"; } return result; } /// /// 订舱生成派车初始信息 /// /// 订舱主键 /// 返回派车初始信息 [HttpGet("/BookingTruck/InitFromBookingOrder")] public async Task InitFromBookingOrder(long bookingId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var model = await InnerCreateTruckFromBookingOrder(bookingId); result.succ = true; result.ext = model; } catch (Exception ex) { result.succ = false; result.msg = $"订舱生成派车初始信息异常,原因:{ex.Message}"; } return result; } /// /// 派车台账查询 /// /// 派车台账查询请求 /// 返回结果 [HttpPost("/BookingTruck/GetPage")] public async Task> GetPageAsync([FromBody] QueryBookingTruckDto QuerySearch) { List contaList = new List(); if (!string.IsNullOrWhiteSpace(QuerySearch.ContaNo)) { if (Regex.IsMatch(QuerySearch.ContaNo, "(\\t|\\n\\r|\\n)")) { contaList = Regex.Replace(QuerySearch.ContaNo, "(\\t |\\n\\r |\\n)", "#").Split(new char[] { '#' }).Select(t => t?.Trim()).ToList(); } else { contaList.Add(QuerySearch.ContaNo.Trim()); } } //制单日期 DateTime createBegin = DateTime.MinValue; DateTime createEnd = DateTime.MinValue; //派车日期 DateTime truckDateBegin = DateTime.MinValue; DateTime truckDateEnd = DateTime.MinValue; //截单日期 DateTime closeDateBegin = DateTime.MinValue; DateTime closeDateEnd = DateTime.MinValue; //提货日期 DateTime pickUpTimeBegin = DateTime.MinValue; DateTime pickUpTimeEnd = DateTime.MinValue; //返场时间 DateTime returnTimeBegin = DateTime.MinValue; DateTime returnTimeEnd = DateTime.MinValue; //要求到达时间 DateTime needArriveTimeBegin = DateTime.MinValue; DateTime needArriveTimeEnd = DateTime.MinValue; #region 查询条件 //制单日期 if (!string.IsNullOrWhiteSpace(QuerySearch.CreateBegin)) { if (!DateTime.TryParse(QuerySearch.CreateBegin, out createBegin)) throw Oops.Oh($"创建起始日期格式错误,{QuerySearch.CreateBegin}"); } if (!string.IsNullOrWhiteSpace(QuerySearch.CreateEnd)) { if (!DateTime.TryParse(QuerySearch.CreateEnd, out createEnd)) throw Oops.Oh($"创建结束日期格式错误,{QuerySearch.CreateEnd}"); createEnd = createEnd.AddDays(1); } //派车日期 if (!string.IsNullOrWhiteSpace(QuerySearch.TruckTimeBegin)) { if (!DateTime.TryParse(QuerySearch.TruckTimeBegin, out truckDateBegin)) throw Oops.Oh($"派车起始日期格式错误,{QuerySearch.TruckTimeBegin}"); } if (!string.IsNullOrWhiteSpace(QuerySearch.TruckTimeEnd)) { if (!DateTime.TryParse(QuerySearch.TruckTimeEnd, out truckDateEnd)) throw Oops.Oh($"派车结束日期格式错误,{QuerySearch.TruckTimeEnd}"); truckDateEnd = truckDateEnd.AddDays(1); } //截单日期 if (!string.IsNullOrWhiteSpace(QuerySearch.ClosingTimeBegin)) { if (!DateTime.TryParse(QuerySearch.ClosingTimeBegin, out closeDateBegin)) throw Oops.Oh($"截单起始日期格式错误,{QuerySearch.ClosingTimeBegin}"); } if (!string.IsNullOrWhiteSpace(QuerySearch.ClosingTimeEnd)) { if (!DateTime.TryParse(QuerySearch.ClosingTimeEnd, out closeDateEnd)) throw Oops.Oh($"截单结束日期格式错误,{QuerySearch.ClosingTimeEnd}"); closeDateEnd = closeDateEnd.AddDays(1); } //提货日期 if (!string.IsNullOrWhiteSpace(QuerySearch.PickUpTimeBegin)) { if (!DateTime.TryParse(QuerySearch.PickUpTimeBegin, out pickUpTimeBegin)) throw Oops.Oh($"提货起始日期格式错误,{QuerySearch.PickUpTimeBegin}"); } if (!string.IsNullOrWhiteSpace(QuerySearch.PickUpTimeEnd)) { if (!DateTime.TryParse(QuerySearch.ClosingTimeEnd, out pickUpTimeEnd)) throw Oops.Oh($"提货结束日期格式错误,{QuerySearch.PickUpTimeEnd}"); pickUpTimeEnd = pickUpTimeEnd.AddDays(1); } //返场时间 if (!string.IsNullOrWhiteSpace(QuerySearch.ReturnTimeBegin)) { if (!DateTime.TryParse(QuerySearch.ReturnTimeBegin, out returnTimeBegin)) throw Oops.Oh($"返场起始日期格式错误,{QuerySearch.ReturnTimeBegin}"); } if (!string.IsNullOrWhiteSpace(QuerySearch.ReturnTimeEnd)) { if (!DateTime.TryParse(QuerySearch.ReturnTimeEnd, out returnTimeEnd)) throw Oops.Oh($"返场结束日期格式错误,{QuerySearch.ReturnTimeEnd}"); returnTimeEnd = returnTimeEnd.AddDays(1); } //要求到达时间 if (!string.IsNullOrWhiteSpace(QuerySearch.NeedArriveTimeBegin)) { if (!DateTime.TryParse(QuerySearch.NeedArriveTimeBegin, out needArriveTimeBegin)) throw Oops.Oh($"返场起始日期格式错误,{QuerySearch.NeedArriveTimeBegin}"); } if (!string.IsNullOrWhiteSpace(QuerySearch.NeedArriveTimeEnd)) { if (!DateTime.TryParse(QuerySearch.NeedArriveTimeEnd, out needArriveTimeEnd)) throw Oops.Oh($"返场结束日期格式错误,{QuerySearch.NeedArriveTimeEnd}"); needArriveTimeEnd = needArriveTimeEnd.AddDays(1); } #endregion string entityOrderCol = "CreatedTime"; //这里因为返回给前端的台账数据是DTO,所以这里排序时候需要转换成Entity对应的字段 if (!string.IsNullOrWhiteSpace(QuerySearch.SortField)) entityOrderCol = MapsterExtHelper.GetAdaptProperty(QuerySearch.SortField); var entities = await _bookingTruckRepository.AsQueryable() .WhereIF(createBegin != DateTime.MinValue, t => t.CreatedTime.HasValue && t.CreatedTime.Value >= createBegin) .WhereIF(createEnd != DateTime.MinValue, t => t.CreatedTime.HasValue && t.CreatedTime.Value < createEnd) .WhereIF(truckDateBegin != DateTime.MinValue, t => t.TruckTime.HasValue && t.TruckTime.Value >= truckDateBegin) .WhereIF(truckDateEnd != DateTime.MinValue, t => t.TruckTime.HasValue && t.TruckTime.Value < truckDateEnd) .WhereIF(closeDateBegin != DateTime.MinValue, t => t.ClosingTime.HasValue && t.ClosingTime.Value >= closeDateBegin) .WhereIF(closeDateEnd != DateTime.MinValue, t => t.ClosingTime.HasValue && t.ClosingTime.Value < closeDateEnd) .WhereIF(pickUpTimeBegin != DateTime.MinValue, t => t.PickUpTime.HasValue && t.PickUpTime.Value >= pickUpTimeBegin) .WhereIF(pickUpTimeEnd != DateTime.MinValue, t => t.PickUpTime.HasValue && t.PickUpTime.Value < pickUpTimeEnd) .WhereIF(returnTimeBegin != DateTime.MinValue, t => t.ReturnTime.HasValue && t.ReturnTime.Value >= returnTimeBegin) .WhereIF(returnTimeEnd != DateTime.MinValue, t => t.ReturnTime.HasValue && t.ReturnTime.Value < returnTimeEnd) .WhereIF(needArriveTimeBegin != DateTime.MinValue, t => t.NeedArriveTime.HasValue && t.NeedArriveTime.Value >= needArriveTimeBegin) .WhereIF(needArriveTimeEnd != DateTime.MinValue, t => t.NeedArriveTime.HasValue && t.NeedArriveTime.Value < needArriveTimeEnd) .WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Yard), t => t.YARDID.Contains(QuerySearch.Yard) || t.YARD.Contains(QuerySearch.Yard)) .WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.InYard), t => t.InYardID.Contains(QuerySearch.Yard) || t.InYard.Contains(QuerySearch.Yard)) .WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Status), t => t.Status == QuerySearch.Status) .OrderBy(entityOrderCol + (QuerySearch.descSort ? " asc " : " desc ")) .ToPagedListAsync(QuerySearch.PageNo, QuerySearch.PageSize); return entities.Adapt>(); } /// /// 订舱主键获取相关派车列表 /// /// 订舱主键 /// 返回派车列表 [HttpGet("/BookingTruck/GetTruckListByBooking")] public async Task> GetTruckListByBookingAsync(long bookingId) { var list = _bookingTruckRepository.AsQueryable().Where(a => a.BookingId == bookingId).ToList(); return list.Adapt>(); } private async Task InnerCreateTruckFromBookingOrder(long bookingId) { BookingTruckShowDto model = null; //取订舱主信息 var orderInfo = _bookingOrderRepository.AsQueryable() .First(a => a.Id == bookingId); if (orderInfo == null) throw Oops.Oh($"订舱主键{bookingId}无法获取业务信息"); model = new BookingTruckShowDto(); model.YARDID = orderInfo.YARDID; model.YARD = orderInfo.YARD; model.InYardID = orderInfo.YARDID; model.InYard = orderInfo.YARD; model.MBLNo = orderInfo.MBLNO; model.Vessel = orderInfo.VESSEL; model.VoyNo = orderInfo.VOYNO; model.YARDCONTRACT = orderInfo.YARDCONTRACT; model.YARDCONTRACTTEL = orderInfo.YARDCONTRACTTEL; model.ClosingTime = orderInfo.CLOSINGDATE; if(orderInfo.CLOSINGDATE.HasValue) { model.ReturnTime = orderInfo.CLOSINGDATE.Value; } model.TruckTime = DateTime.Now; model.FromName = UserManager.Name; model.FromTel = UserManager.TEl; model.FromMail = UserManager.Email; model.FromMobile = UserManager.Phone; //这里岗位是调度的信息,如果默认只有一条记录,取第一条,其他情况不返回默认值 var userPosInfo = await _sysUserService.QueryUserByPos("", "PCDD"); if (userPosInfo.Count == 1) { model.DispatcherId = userPosInfo.FirstOrDefault().SysEmpId; model.DispatcherName = userPosInfo.FirstOrDefault().SysEmpName; } var yardList = await _djyCustomerService.QuerytDjyCustomerInfo("", new string[] { "yard" }, 999); if (yardList.Count > 0) { if ((string.IsNullOrWhiteSpace(model.YARDCONTRACT) || string.IsNullOrWhiteSpace(model.YARDCONTRACTTEL)) && !string.IsNullOrWhiteSpace(model.YARD)) { var currYardList = yardList.Select(a => { return new { KNum = a.ShortName.IndexOf(model.YARD), Equls = a.ShortName.Equals(model.YARD, StringComparison.OrdinalIgnoreCase) ? 1 : 0, Obj = a }; }).Where(a => a.KNum >= 0).ToList(); if (currYardList.Count > 0) { var yardInfo = currYardList .OrderByDescending(a => a.Equls) .ThenBy(a => a.KNum) .FirstOrDefault().Obj; if (yardInfo != null) { if (string.IsNullOrWhiteSpace(model.YARDCONTRACT)) { model.YARDCONTRACT = yardInfo.Chief?.Trim(); } if (string.IsNullOrWhiteSpace(model.YARDCONTRACTTEL)) model.YARDCONTRACTTEL = yardInfo.Tel?.Trim(); } } } } model.InYardContact = model.YARDCONTRACT; model.InYardContractTel = model.YARDCONTRACTTEL; if (orderInfo.KGS.HasValue) { //计算总吨数 model.KGS = Math.Round(orderInfo.KGS.Value / 1000m, 3); } //取订舱箱列表 var ctnList = _bookingCtnRepository.AsQueryable() .Where(a => a.BILLID == bookingId).ToList(); if (ctnList.Count > 0) { model.ContaList = new List(); ctnList.ForEach(b => { if (b.CTNNUM == 1) { model.ContaList.Add(new BookingTruckCtnDto { CTNCODE = b.CTNCODE, CTNALL = b.CTNALL, KGS = b.KGS, PKGS = b.PKGS, CBM = b.CBM, TAREWEIGHT = b.TAREWEIGHT, CNTRNO = b.CNTRNO, KINDPKGS = b.KINDPKGS, SEALNO = b.SEALNO, TEU = b.TEU, CTNNUM = 1, }); } else { for (int i = 0; i < b.CTNNUM; i++) { model.ContaList.Add(new BookingTruckCtnDto { CTNCODE = b.CTNCODE, CTNALL = b.CTNALL, KGS = b.KGS, PKGS = b.PKGS, CBM = b.CBM, TAREWEIGHT = b.TAREWEIGHT, CNTRNO = b.CNTRNO, KINDPKGS = b.KINDPKGS, SEALNO = b.SEALNO, TEU = b.TEU, CTNNUM = 1, }); } } }); } return model; } /// /// 引入订舱详情生成派车信息 /// /// 订舱主键 /// 返回派车初始信息 [HttpGet("/BookingTruck/PullInBookingOrder")] public async Task PullInBookingOrder(long bookingId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var model = await InnerCreateTruckFromBookingOrder(bookingId); result.succ = true; result.ext = model; } catch (Exception ex) { result.succ = false; result.msg = $"引入订舱详情生成派车信息异常,原因:{ex.Message}"; } return result; } /// /// 引入订舱集装箱详情生成派车信息 /// /// 订舱主键 /// 返回派车集装箱初始信息 [HttpGet("/BookingTruck/PullInBookingOrderConta")] public async Task PullInBookingOrderConta(long bookingId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var model = await InnerCreateTruckFromBookingOrder(bookingId); result.succ = true; if (model != null && model.ContaList != null && model.ContaList.Count > 0) { result.ext = model.ContaList; } } catch (Exception ex) { result.succ = false; result.msg = $"引入订舱详情生成派车信息异常,原因:{ex.Message}"; } return result; } /// /// 提交派车 /// /// 派车信息 /// 返回回执 [HttpPost("/BookingTruck/Submit")] public async Task Submit(BookingTruckDto info) { string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no}获取提交派车请求 {id}", batchNo, info.Id); TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { result = await InnerSubmit(info, batchNo); } catch (Exception ex) { result.succ = false; result.msg = ex.GetMessage(); } return result; } #region 提交内部方法 /// /// 提交内部方法 /// /// 派车信息 /// 批次号 /// 返回回执 private async Task InnerSubmit(BookingTruckDto info, string batchNo, bool isDefaultSave = true) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); /* 提交派车流程 1、先保存一遍派车信息。(需校验当前派车信息未提交,只有暂存的才能保存) 2、调取派车任务接口推送派车任务。 3、派车任务推送成功后更新状态、任务ID。 4、返回结果。 */ try { //先保存 var id = info.Id; if (isDefaultSave) id = InnerSave(info).GetAwaiter().GetResult(); //校验 var model = _bookingTruckRepository.AsQueryable().First(a => a.Id == id); if (model == null) throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException)); var bookingOrder = _bookingOrderRepository.AsQueryable().First(a => a.Id == model.BookingId); //校验 ValidateTruck(OperateTypeEnum.Submit, new BookingTruck[] { model }); var contaList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == id).ToList(); DateTime bDate = DateTime.Now; string vesselVoyno = string.Empty; if(!string.IsNullOrWhiteSpace(bookingOrder.VESSEL)) { vesselVoyno = bookingOrder.VESSEL; } if (!string.IsNullOrWhiteSpace(bookingOrder.VOYNO)) { vesselVoyno = $"{vesselVoyno}/{bookingOrder.VOYNO}"; } TaskManageOrderMessageInfo messageInfo = new TaskManageOrderMessageInfo { Head = new TaskManageOrderMessageHeadInfo { GID = id.ToString(),//直接用派车的主键 MessageType = "TASK", SenderId = "BookingOrder", SenderName = "订舱派车", ReceiverId = "TaskManage", ReceiverName = "派车任务", RequestDate = bDate.ToString("yyyy-MM-dd HH:mm:ss.fff"), Version = "1.0", RequestAction = "Add" }, Main = new TaskManageOrderMessageMainInfo { TaskType = TaskBaseTypeEnum.TRUCK_DISPATCH, TruckInfo = model.Adapt(), MBlNo = bookingOrder.MBLNO, ETD = bookingOrder.ETD, VesselVoyno = vesselVoyno, TaskUserId = UserManager.UserId.ToString(), TaskUserName = UserManager.Name, ContaInfo = model.CntrTotal, YardName = model.InYard, CarrierId = bookingOrder.CARRIERID, CustomerId = bookingOrder.CUSTOMERID, CustomerName = bookingOrder.CUSTOMERNAME } }; if(string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.Vessel) && !string.IsNullOrWhiteSpace(bookingOrder.VESSEL)) { messageInfo.Main.TruckInfo.Vessel = bookingOrder.VESSEL; } if (string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.VoyNo) && !string.IsNullOrWhiteSpace(bookingOrder.VOYNO)) { messageInfo.Main.TruckInfo.VoyNo = bookingOrder.VOYNO; } if (string.IsNullOrWhiteSpace(messageInfo.Main.TruckInfo.MBLNo) && !string.IsNullOrWhiteSpace(bookingOrder.MBLNO)) { messageInfo.Main.TruckInfo.MBLNo = bookingOrder.MBLNO; } if (contaList.Count > 0) messageInfo.Main.TruckInfo.ContaList = contaList.Adapt>(); messageInfo.Main.TaskUserId = UserManager.UserId.ToString(); messageInfo.Main.TaskUserName = UserManager.Name; messageInfo.Main.RecvUserId = model.DispatcherId.ToString(); messageInfo.Main.RecvUserName = model.DispatcherName; messageInfo.Main.TaskTitle = $"{model.TruckFlowNo}_派车任务"; messageInfo.Main.TaskDesp = $"{model.TruckFlowNo}_派车任务"; messageInfo.Main.TaskSource = TaskSourceEnum.CUSTOMER_SUBMIT; _logger.LogInformation("批次={no} 请求报文msg={msg}", batchNo, JSON.Serialize(messageInfo)); //推送新增派车任务接口 var taskRlt = await _taskManageExternalService.SubmitTruckDispatchAsync(messageInfo); DateTime eDate = DateTime.Now; TimeSpan ts = eDate.Subtract(bDate); var timeDiff = ts.TotalMilliseconds; _logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(taskRlt)); if (!taskRlt.succ) { throw Oops.Oh($"请求派车调度失败,原因={taskRlt.msg}", typeof(InvalidOperationException)); } //更新派车订单为已提交 model.Status = BookingTruckStatus.SUBMITED.ToString(); model.UpdatedTime = DateTime.Now; model.UpdatedUserId = UserManager.UserId; model.UpdatedUserName = UserManager.Name; //提取任务流水号 if (taskRlt.ext != null) model.TaskNo = taskRlt.ext.ToString(); await _bookingTruckRepository.AsUpdateable(model).UpdateColumns(it => new { it.Status, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName, it.TaskNo }).ExecuteCommandAsync(); result.succ = true; result.msg = "提交成功"; //这里直接调用订舱服务的功能,担心有异常所以这里单独做了异常捕获 try { //派车后填写货物状态 await _bookingOrderService.SetGoodsStatus("YPC", bookingOrder.Id); _logger.LogInformation("批次={no} id={id} 更新订舱的货物状态完成", batchNo, bookingOrder.Id); } catch(Exception bkException) { _logger.LogInformation("批次={no} id={id} 更新订舱的货物状态 YPC异常,原因:{erro}", batchNo, bookingOrder.Id, bkException.Message); } //这里直接调用订舱服务的功能,担心有异常所以这里单独做了异常捕获 try { //触发发送东胜 var currRlt = await _bookingOrderService.SendBookingOrder(new long[] { bookingOrder.Id }); string curMsg = JSON.Serialize(currRlt); _logger.LogInformation("批次={no} id={id} 触发发送东胜完成 结果={rlt}", batchNo, bookingOrder.Id, curMsg); } catch (Exception bkException) { _logger.LogInformation("批次={no} id={id} 触发发送东胜完成,原因:{erro}", batchNo, bookingOrder.Id, bkException.Message); } } catch (Exception ex) { result.succ = false; result.msg = ex.GetMessage("提交失败"); } return result; } #endregion #region 批量提交派车 /// /// 批量提交派车 /// /// 派车主键组 /// 返回回执 [HttpPost("/BookingTruck/SubmitBatch")] public async Task SubmitBatch([FromBody] long[] ids) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no}获取提交派车请求 {ids}", batchNo, ids); try { var list = _bookingTruckRepository.AsQueryable() .Where(a => ids.Contains(a.Id)).ToList(); if (list.Count != ids.Length) throw Oops.Oh($"部分派车信息获取失败,不能提交,派车信息不存在或已作废"); //校验 ValidateTruck(OperateTypeEnum.Submit, list.ToArray()); List> taskList = new List>(); list.ForEach(async tk => { taskList.Add(InnerSubmit(new BookingTruckDto { Id = tk.Id }, batchNo, false)); }); //等待所有结果 Task.WaitAll(taskList.ToArray(), 20000); result.succ = true; result.msg = "提交成功"; List msgList = new List(); taskList.ForEach(async a => { var rlt = a.Result; if (!rlt.succ) { result.succ = false; msgList.Add($"派车单号:{rlt.ext.ToString()},{rlt.msg}"); result.msg = "提交失败"; } }); result.ext = msgList; } catch (Exception ex) { result.succ = false; result.msg = $"批量提交派车异常,原因:{ex.Message}"; } return result; } #endregion /// /// 撤销派车 /// /// 派车主键 /// 返回回执 [HttpGet("/BookingTruck/Cancel")] public async Task Cancel(long id) { /* 撤销派车流程 1、确定当前派车已提交。 2、调取取消派车任务接口,申请撤销派车。 3、取消派车推送成功后更新状态。 4、返回结果。 */ string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no}获取撤销派车请求 {id}", batchNo, id); TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { result = await InnerCancel(id, batchNo); } catch (Exception ex) { result.succ = false; result.msg = ex.GetMessage(); } return result; } /// /// 批量撤销派车 /// /// 派车主键组 /// 返回回执 [HttpPost("/BookingTruck/CancelBatch")] public async Task CancelBatch([FromBody] long[] ids) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); /* 批量撤销派车流程 1、确定当前派车已提交。 2、调取取消派车任务接口,申请撤销派车。 3、取消派车推送成功后更新状态。 4、返回结果。 */ string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no}获取撤销派车请求 {ids}", batchNo, ids); try { var list = _bookingTruckRepository.AsQueryable() .Where(a => ids.Contains(a.Id)).ToList(); if (list.Count != ids.Length) throw Oops.Oh($"部分派车信息获取失败,不能撤销,派车信息不存在或已作废"); //校验 ValidateTruck(OperateTypeEnum.Submit, list.ToArray()); List> taskList = new List>(); list.ForEach(async tk => { taskList.Add(InnerCancel(tk.Id, batchNo)); }); //等待所有结果 Task.WaitAll(taskList.ToArray(), 20000); result.succ = true; result.msg = "撤销成功"; List msgList = new List(); taskList.ForEach(async a => { var rlt = a.Result; if (!rlt.succ) { result.succ = false; msgList.Add($"派车单号:{rlt.ext.ToString()},{rlt.msg}"); result.msg = "撤销失败"; } }); result.ext = msgList; } catch (Exception ex) { result.succ = false; result.msg = $"撤销派车异常,原因:{ex.Message}"; } return result; } #region 内部撤销派车 /// /// 内部撤销派车 /// /// 派车主键 /// 批次号 /// 返回回执 private async Task InnerCancel(long id, string batchNo) { /* 撤销派车流程 1、确定当前派车已提交。 2、调取取消派车任务接口,申请撤销派车。 3、取消派车推送成功后更新状态。 4、返回结果。 */ TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { //校验 var model = _bookingTruckRepository.AsQueryable().First(a => a.Id == id); if (model == null) throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException)); //校验 ValidateTruck(OperateTypeEnum.Cancel, new BookingTruck[] { model }); DateTime bDate = DateTime.Now; TaskManageOrderMessageInfo messageInfo = new TaskManageOrderMessageInfo { Head = new TaskManageOrderMessageHeadInfo { GID = id.ToString(),//直接用派车的主键 MessageType = "TASK", SenderId = "BookingOrder", SenderName = "订舱派车", ReceiverId = "TaskManage", ReceiverName = "派车任务", RequestDate = bDate.ToString("yyyy-MM-dd HH:mm:ss.fff"), Version = "1.0", RequestAction = "Add" }, Main = new TaskManageOrderMessageMainInfo { TaskType = TaskBaseTypeEnum.TRUCK_DISPATCH, TruckInfo = model.Adapt(), } }; messageInfo.Main.TaskUserId = UserManager.UserId.ToString(); messageInfo.Main.TaskUserName = UserManager.Name; messageInfo.Main.TaskTitle = $"{model.MBLNo}_派车任务"; messageInfo.Main.TaskDesp = $"{model.MBLNo}_派车任务"; messageInfo.Main.TaskSource = TaskSourceEnum.CUSTOMER_SUBMIT; _logger.LogInformation("批次={no} 请求报文msg={msg}", batchNo, JSON.Serialize(messageInfo)); //推送取消派车任务接口 var taskRlt = await _taskManageExternalService.CancelTruckDispatchAsync(messageInfo); DateTime eDate = DateTime.Now; TimeSpan ts = eDate.Subtract(bDate); var timeDiff = ts.TotalMilliseconds; _logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(taskRlt)); if (!taskRlt.succ) { throw Oops.Oh($"请求撤销派车调度失败,原因={taskRlt.msg}", typeof(InvalidOperationException)); } //操作取消派车任务成功后,立即触发清空订舱的车队信息,并触发东胜同步删除 BookingTruckDto bookingTruckDto = model.Adapt(); bookingTruckDto.CallBackStatus = BookingTruckStatus.CANCEL_DISPATCH.ToString(); var truckCtnList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == model.Id).ToList(); if (truckCtnList.Count > 0) bookingTruckDto.ContaList = truckCtnList.Adapt>(); bookingTruckDto.Id = model.Id; _logger.LogInformation("批次={no} 准备触发取消回写 报文={msg}", batchNo, JSON.Serialize(bookingTruckDto)); //触发取消回写 var callBackRlt = await TruckDispatchCompleteCallBack(bookingTruckDto); _logger.LogInformation("批次={no} 准备触发取消回写 结果={msg}", batchNo, JSON.Serialize(callBackRlt)); //更新派车订单为已提交 model.Status = BookingTruckStatus.CANCELED.ToString(); model.UpdatedTime = DateTime.Now; model.UpdatedUserId = UserManager.UserId; model.UpdatedUserName = UserManager.Name; model.TaskNo = null; await _bookingTruckRepository.AsUpdateable(model).UpdateColumns(it => new { it.Status, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName, it.TaskNo }).ExecuteCommandAsync(); result.succ = true; result.msg = "撤销成功"; } catch (Exception ex) { result.succ = false; result.msg = ex.GetMessage("撤销失败"); } return result; } #endregion /// /// 删除派车 /// /// 派车主键 /// 返回回执 [HttpGet("/BookingTruck/Delete")] public async Task Delete(long id) { //检索 var truckOrder = _bookingTruckRepository.AsQueryable().First(a => a.Id == id); if (truckOrder == null) throw Oops.Oh($"派车信息获取失败,派车信息不存在或已作废", typeof(InvalidOperationException)); //先校验 ValidateTruck(OperateTypeEnum.Delete, new BookingTruck[] { truckOrder }); await _bookingTruckRepository.UpdateAsync(x => x.Id == id, x => new BookingTruck { IsDeleted = true }); _logger.LogInformation("删除派车成功 id={id} user={usr}", id, UserManager.UserId); return "删除成功"; } /// /// 批量删除派车 /// /// 派车主键组 /// 返回回执 [HttpPost("/BookingTruck/DeleteBatch")] public async Task DeleteBatch([FromBody] long[] ids) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { //检索 var truckOrderList = _bookingTruckRepository.AsQueryable() .Where(a => ids.Contains(a.Id)).ToList(); if (truckOrderList.Count != ids.Length) throw Oops.Oh($"部分派车信息获取失败,派车信息不存在或已作废"); //先校验 ValidateTruck(OperateTypeEnum.Delete, truckOrderList.ToArray()); truckOrderList.ForEach(async tk => { await _bookingTruckRepository.UpdateAsync(x => x.Id == tk.Id, x => new BookingTruck { IsDeleted = true }); }); result.succ = true; result.msg = "删除成功"; _logger.LogInformation("删除派车成功 ids={id} user={usr}", ids, UserManager.UserId); } catch (Exception ex) { result.succ = false; result.msg = ex.GetMessage("删除派车异常"); } return result; } /// /// 获取订舱打印模板列表(带有当前用户打印历史排序) /// /// 分类代码(使用字典【booking_template_category】中的代码) /// 打印分类,10:FastReport、20:Excel模板 /// [HttpGet("/BookingTruck/PrintTemplateWithHistoryList")] public async Task PrintTemplateWithHistoryList(string cateCode, BookingPrintTemplateType printType) { var typeCode = printType.ToString(); //当前公司所有已配置的模板 var allList = await _bookingPrintTemplateRepository.AsQueryable() .Filter(null, true).InnerJoin((d, t) => d.Id == t.PrintTemplateId && t.SysUserId == UserManager.UserId) .Where(d => d.TenantId == UserManager.TENANT_ID && d.CateCode.Contains(cateCode) && d.Type == typeCode) .Select(d => new { d.Id, d.CateCode, d.CateName, d.DisplayName }) .ToListAsync(); var listReult = new List(); //当前用户打印历史数据 var printRecentListKey = $"{PRINT_LIST_TYPE_KEY}_{cateCode}_{printType}"; var usrCfg = await _djyUserConfigConfig.AsQueryable().FirstAsync(x => x.CreatedUserId == UserManager.UserId && x.Type == printRecentListKey); if (usrCfg != null) { var arr = JArray.Parse(usrCfg.ConfigJson).Select(x => Convert.ToInt64(x)).ToList(); //按顺序加入到结果 arr.ForEach(x => { var find = allList.FirstOrDefault(y => y.Id == x); if (find != null) { listReult.Add(find); } }); var listOut = allList.Where(x => !arr.Contains(x.Id)).ToList(); listReult.AddRange(listOut); return listReult; } else { return allList; } } /// /// 打印派车 /// /// 派车主键 /// 打印模板ID /// 分类代码(使用字典【booking_template_category】中的代码) /// 类型,1:pdf、2:xlsx、3:docx /// 打印类型,10:FastReport、20:Excel模板 /// 返回回执 [HttpGet("/BookingTruck/Print")] public async Task Print([FromQuery] long id, [FromQuery] long templateId, [FromQuery] string cateCode, [FromQuery] PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF, [FromQuery] BookingPrintTemplateType printType = BookingPrintTemplateType.FastReport) { var printTemplate = await _bookingPrintTemplateRepository.AsQueryable().Filter(null, true) .FirstAsync(x => x.Id == templateId); if (printTemplate == null) { throw Oops.Bah(BookingErrorCode.BOOK115); } var truckOrder = await _bookingTruckRepository.FirstOrDefaultAsync(x => x.Id == id); if (!truckOrder.NeedArriveTime.HasValue) { throw Oops.Oh("要求送达日期不能为空"); } //var edi = await _bookingEDIExt.FirstOrDefaultAsync(x => x.BookingId == bookingId); //if (order == null) //{ // throw Oops.Bah(BookingErrorCode.BOOK001); //} var fileName = string.Empty; //var dicCate = (await _cache.GetAllDictData()).FirstOrDefault(x => x.Code == cateCode && x.TypeCode == "booking_template_category"); //if (dicCate == null) //{ // throw Oops.Bah("分类代码参数不正确"); //} if (printType == BookingPrintTemplateType.FastReport) { #region FastReport打印 var bs = await GenPrintFile(id, printTemplate, printFileType); var fileType = ""; if (printFileType == PrintFileTypeEnum.PDF) { fileType = ".pdf"; } else if (printFileType == PrintFileTypeEnum.XLSX) { fileType = ".xlsx"; } else if (printFileType == PrintFileTypeEnum.DOCX) { fileType = ".docx"; } else { throw Oops.Bah("类型参数不正确"); } fileName = $"{DateTime.Now.Ticks}{fileType}";//名称 ////2023-4-3,根据河川操作要求,文件名只带提单号 //if (!string.IsNullOrEmpty(order.MBLNO)) //{ // fileName = $"{order.MBLNO}{fileType}";//名称 //} //else //{ // fileName = $"{order.Id}_{DateTime.Now.Ticks}{fileType}";//名称 //} var opt = App.GetOptions().Path; var serverpath = Path.Combine(App.WebHostEnvironment.WebRootPath, opt);//服务器路径 if (!Directory.Exists(serverpath)) { Directory.CreateDirectory(serverpath); } var fullPath = Path.Combine(serverpath, fileName); await File.WriteAllBytesAsync(fullPath, bs); #endregion } /* else if (printType == BookingPrintTemplateType.ExcelTemplate) { #region Excel模板打印 var opt = App.GetOptions(); var dirAbs = opt.basePath; if (string.IsNullOrEmpty(dirAbs)) { dirAbs = App.WebHostEnvironment.WebRootPath; } var fileAbsPath = Path.Combine(dirAbs, printTemplate.FilePath); _logger.LogInformation($"准备调用EXCEL生成:id:{id},文件:{printTemplate.FileName}"); var result = new FileStream(fileAbsPath, FileMode.Open); var excelwork = new HSSFWorkbook(result); var sheet = excelwork.GetSheetAt(0); var entity = await _bookingExcelTemplateRepository.AsQueryable() .Where(x => x.PId == templateId).OrderBy(x => x.Row).ToListAsync(); if (entity == null) { throw Oops.Bah("当前模板未设置"); } for (int _row = 1; _row <= entity.Max(x => x.Row); _row++) { if (entity.Where(x => x.Row == _row).Count() > 0) { ////获取行 var row = sheet.GetRow(_row - 1); if (row != null) { for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) { if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) { var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); if (name.Split('.')[0].ToLower() == "order") { foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) { var _name = descriptor.Name.ToLower(); if (name.Split('.')[0].ToLower() == "order" && name.Split('.')[1].ToLower() == _name) { var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; ICell cell = row.GetCell(_cellNum - 1); if (descriptor.PropertyType.FullName.Contains("DateTime")) { value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; } if (cell != null) { row.Cells[_cellNum - 1].SetCellValue(value); } else { row.CreateCell(_cellNum - 1).SetCellValue(value); } } } } if (name.Split('.')[0].ToLower() == "edi") { foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) { var _name = descriptor.Name.ToLower(); if (name.Split('.')[0].ToLower() == "edi" && name.Split('.')[1].ToLower() == _name) { var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; ICell cell = row.GetCell(_cellNum - 1); if (descriptor.PropertyType.FullName.Contains("DateTime")) { value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; } if (cell != null) { row.Cells[_cellNum - 1].SetCellValue(value); } else { row.CreateCell(_cellNum - 1).SetCellValue(value); } } } } if (name.Split('.')[0].ToLower() == "userinfo") { ICell cell = row.GetCell(_cellNum - 1); var value = string.Empty; if (name.Split('.')[1].ToLower() == "username") { value = UserManager.Name; } if (name.Split('.')[1].ToLower() == "usertel") { value = UserManager.TEl; } if (name.Split('.')[1].ToLower() == "usermobile") { value = UserManager.Phone; } if (name.Split('.')[1].ToLower() == "useremail") { value = UserManager.Email; } if (name.Split('.')[1].ToLower() == "usertenant") { value = UserManager.TENANT_NAME; } if (cell != null) { row.Cells[_cellNum - 1].SetCellValue(value); } else { row.CreateCell(_cellNum - 1).SetCellValue(value); } } } } } else { ////创建行 var srow = NpoiExcelExportHelper._.CreateRow(sheet, _row - 1); for (int _cellNum = 1; _cellNum <= entity.Max(x => x.Column); _cellNum++) { if (entity.Where(x => x.Row == _row && x.Column == _cellNum).Count() > 0) { var name = entity.Where(x => x.Row == _row && x.Column == _cellNum).Select(x => x.Field).FirstOrDefault(); if (name.Split('.')[0].ToLower() == "order") { foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(order)) { var _name = descriptor.Name.ToLower(); if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "order") { var value = descriptor.GetValue(order) != null ? descriptor.GetValue(order).ToString() : ""; if (descriptor.PropertyType.FullName.Contains("DateTime")) { value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; } srow.CreateCell(_cellNum - 1).SetCellValue(value); } } } if (name.Split('.')[0].ToLower() == "edi") { foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(edi)) { var _name = descriptor.Name.ToLower(); if (name.Split('.')[1].ToLower() == _name && name.Split('.')[0].ToLower() == "edi") { var value = descriptor.GetValue(edi) != null ? descriptor.GetValue(edi).ToString() : ""; if (descriptor.PropertyType.FullName.Contains("DateTime")) { value = value != "" ? Convert.ToDateTime(value).ToString("yyyy-MM-dd") : ""; } srow.CreateCell(_cellNum - 1).SetCellValue(value); } } } if (name.Split('.')[0].ToLower() == "userinfo") { var value = string.Empty; if (name.Split('.')[1].ToLower() == "username") { value = UserManager.Name; } if (name.Split('.')[1].ToLower() == "usertel") { value = UserManager.TEl; } if (name.Split('.')[1].ToLower() == "usermobile") { value = UserManager.Phone; } if (name.Split('.')[1].ToLower() == "useremail") { value = UserManager.Email; } if (name.Split('.')[1].ToLower() == "usertenant") { value = UserManager.TENANT_NAME; } srow.CreateCell(_cellNum - 1).SetCellValue(value); } } } } } } var fileFullPath = Path.Combine(App.WebHostEnvironment.WebRootPath, App.GetOptions().Path);//服务器路径 if (!Directory.Exists(fileFullPath)) { Directory.CreateDirectory(fileFullPath); } fileName = $"{DateTime.Now.Ticks}.xls";//名称 ////2023-4-3,根据河川操作要求,文件名只带提单号 //if (!string.IsNullOrEmpty(order.MBLNO)) //{ // fileName = $"{order.MBLNO}.xls";//名称 //} //else //{ // fileName = $"{order.Id}_{DateTime.Now.Ticks}.xls";//名称 //} _logger.LogInformation("导出excel:" + Path.Combine(fileFullPath, fileName)); var filestream = new FileStream(Path.Combine(fileFullPath, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite); excelwork.Write(filestream); #endregion } */ //记录打印次数和时间,用于前端动态展示常用的打印类型 var printRecentListKey = $"{PRINT_LIST_TYPE_KEY}_{cateCode}_{printType}"; var usrCfg = _djyUserConfigConfig.AsQueryable().First(x => x.CreatedUserId == UserManager.UserId && x.Type == printRecentListKey); if (usrCfg == null) { usrCfg = new DjyUserConfig(); usrCfg.Type = printRecentListKey; usrCfg.ConfigJson = (new long[] { templateId }).ToJson(); await _djyUserConfigConfig.InsertAsync(usrCfg); } else { var arr = JArray.Parse(usrCfg.ConfigJson).Select(x => Convert.ToInt64(x)).Where(x => x != templateId).ToList(); arr.Insert(0, templateId); usrCfg.ConfigJson = arr.ToArray().ToJson(); await _djyUserConfigConfig.UpdateAsync(usrCfg); } return HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8")); } /// /// 生成打印报表文件 /// /// 派车ID /// 打印模板 /// 文档类型,1:pdf、2:xlsx、3:docx /// 返回文件流 [NonAction] private async Task GenPrintFile(long bookingTruckId, BookingPrintTemplate printTemplate, PrintFileTypeEnum printFileType = PrintFileTypeEnum.PDF) { //打印报表服务地址 var reportUrl = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "url_report_generate").Value; if (!reportUrl.EndsWith("/")) { reportUrl += "/"; } var truckOrder = _bookingTruckRepository.AsQueryable().First(a => a.Id == bookingTruckId); if (truckOrder == null) throw Oops.Oh($"派车主键{bookingTruckId}无法获取业务信息"); var truckCtnList = _bookingTruckContaRepository.AsQueryable().Where(a => a.TruckId == bookingTruckId).ToList(); BookingOrder bookingOrder = null; if (truckOrder.BookingId.HasValue && truckOrder.BookingId.Value > 0) { bookingOrder = _bookingOrderRepository.AsQueryable().First(a => a.Id == truckOrder.BookingId.Value); } BookingTruckPrintDto model = truckOrder.Adapt(); model.IsGuaJi = truckOrder.IsGuaJi ? "需要挂机" : "无"; if (bookingOrder != null) { model.Vessel = bookingOrder.VESSEL; if (!string.IsNullOrWhiteSpace(bookingOrder.VOYNO)) { model.VoyNo = bookingOrder.VOYNO; } else { model.VoyNo = bookingOrder.VOYNOINNER; } model.MBLNo = bookingOrder.MBLNO; model.CarrierID = bookingOrder.CARRIERID; model.Carrier = bookingOrder.CARRIER; model.DestinationID = bookingOrder.DESTINATIONID; model.Destination = bookingOrder.DESTINATION; model.ETD = bookingOrder.ETD; } if (truckCtnList.Count > 0) model.ContaList = truckCtnList.Adapt>(); _logger.LogInformation($"bookingTruckId={bookingTruckId} 请求打印 JSON={JSON.Serialize(model)}"); return await PrintHelper.GeneratePrintFile(JSON.Serialize(model), reportUrl, PRINT_DATASOURCE_KEY, printFileType, printTemplate); } #region 校验派车 /// /// 校验派车 /// /// 操作类型 /// 派车信息列表 private void ValidateTruck(OperateTypeEnum operateType, BookingTruck[] entityArg) { if (operateType == OperateTypeEnum.Save) { if (entityArg.Any(a => a.Status != BookingTruckStatus.TEMP.ToString() && a.Status != BookingTruckStatus.CANCELED.ToString())) { throw Oops.Oh($"派车状态只有暂存、已撤销才能保存", typeof(InvalidOperationException)); } } else if (operateType == OperateTypeEnum.Submit) { if (entityArg.Any(a => a.Status != BookingTruckStatus.TEMP.ToString() && a.Status != BookingTruckStatus.CANCELED.ToString())) { throw Oops.Oh($"派车状态只有暂存、已撤销才能提交", typeof(InvalidOperationException)); } if (entityArg.Any(a => !a.DispatcherId.HasValue || (a.DispatcherId.HasValue && a.DispatcherId.Value == 0))) { throw Oops.Oh($"未填写调度,不能提交", typeof(InvalidOperationException)); } if (entityArg.Any(a => !a.NeedArriveTime.HasValue)) { throw Oops.Oh($"未填写要求送达日期,不能提交", typeof(InvalidOperationException)); } } else if (operateType == OperateTypeEnum.Cancel) { if (entityArg.Any(a => a.Status != BookingTruckStatus.SUBMITED.ToString() && a.Status != BookingTruckStatus.SEND_DISPATCH.ToString())) { throw Oops.Oh($"派车状态只有已提交、已派车才能撤销派车", typeof(InvalidOperationException)); } } else if (operateType == OperateTypeEnum.Delete) { if (entityArg.Any(a => a.Status != BookingTruckStatus.TEMP.ToString() && a.Status != BookingTruckStatus.CANCELED.ToString())) { throw Oops.Oh($"派车状态只有暂存、已撤销才能作废", typeof(InvalidOperationException)); } } else if (operateType == OperateTypeEnum.DispatchBackSave) { if (entityArg.Any(a => a.Status != BookingTruckStatus.SUBMITED.ToString() && a.Status != BookingTruckStatus.SEND_DISPATCH.ToString() && a.Status != BookingTruckStatus.CANCEL_DISPATCH.ToString())) { throw Oops.Oh($"派车状态只有已提交才能回写详情", typeof(InvalidOperationException)); } } } #endregion /// /// 派车任务回写派车详情 /// /// 派车详情 /// 返回回执 [HttpPost("/BookingTruck/TruckDispatchCompleteCallBack")] public async Task TruckDispatchCompleteCallBack(BookingTruckDto info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); result.ext2 = info.Id; try { /* 回写逻辑 1、派车任务完成发送派车后,自动回写派车任务表的详情 2、需校验如果派车不是已提交,不能回写。 3、比较差异留存。 */ var bookingTruckInfo = _bookingTruckRepository.AsQueryable().First(a => a.Id == info.Id); if (bookingTruckInfo == null) throw Oops.Oh($"派车信息不存在", typeof(InvalidOperationException)); if (bookingTruckInfo.Status != BookingTruckStatus.SUBMITED.ToString() && bookingTruckInfo.Status != BookingTruckStatus.SEND_DISPATCH.ToString() && bookingTruckInfo.Status != BookingTruckStatus.CANCEL_DISPATCH.ToString()) throw Oops.Oh($"当前派车信息不是已提交状态不能接收回写", typeof(InvalidOperationException)); var id = await InnerSave(info, true); BookingTruckSyncMessageInfo messageInfo = new BookingTruckSyncMessageInfo(); string batchNo = IDGen.NextID().ToString(); messageInfo.Head = new BookingTruckSyncMessageHeadInfo { GID = info.Id.ToString(), MessageType = "TRUCK_SYNC", SenderId = "BOOKING_TRUCK", SenderName = "订舱派车", SenderKey = "BOOKING_TRUCK", ReceiverId = "DongshengHeChuan", ReceiverName = "东胜和川", Version = "1.0", RequestDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), RequestAction = "Sync", }; BookingTruckSyncMessageMainInfo bookingTruckSyncDto = info.Adapt(); bookingTruckSyncDto.ContaList = info.ContaList.Adapt>(); if (info.CallBackStatus == BookingTruckStatus.CANCEL_DISPATCH.ToString()) { bookingTruckSyncDto.OperType = "Delete"; var bookingOrder = _bookingOrderRepository.AsQueryable() .First(a => a.Id == bookingTruckInfo.BookingId.Value); if (bookingOrder != null) { _logger.LogInformation("判断回写需要更新去掉订舱的车队 id={id} truckid={truckid} truck={truck}", bookingTruckInfo.BookingId.Value, bookingOrder.TRUCKERID, bookingOrder.TRUCKER); bookingOrder.TRUCKERID = null; bookingOrder.TRUCKER = null; bookingOrder.VERSION = IDGen.NextID().ToString().Replace("-", ""); _bookingOrderRepository.AsUpdateable(bookingOrder).UpdateColumns(it => new { it.TRUCKERID, it.TRUCKER, it.VERSION }).ExecuteCommand(); var syncDongshengRlt = await _bookingOrderService.SendBookingOrder(new long[] { bookingTruckInfo.BookingId.Value }); _logger.LogInformation($"推送订舱同步东胜完毕,id={bookingTruckInfo.BookingId.Value} rlt={JSON.Serialize(syncDongshengRlt)}"); _logger.LogInformation("判断回写需要更新去掉订舱的车队,更新完成"); } } else { bookingTruckSyncDto.OperType = "AddOrUpdate"; //这里增加判断如果派车回写里包含车队信息,自动回写到订舱信息里 if (!string.IsNullOrWhiteSpace(info.TruckCode)) { var bookingOrder = _bookingOrderRepository.AsQueryable() .First(a => a.Id == bookingTruckInfo.BookingId.Value); if (bookingOrder != null) { _logger.LogInformation("判断回写需要更新订舱的车队 id={id} truck={truck}", bookingTruckInfo.BookingId.Value, info.TruckName); bookingOrder.TRUCKERID = info.TruckCode; bookingOrder.TRUCKER = info.TruckName; bookingOrder.VERSION = IDGen.NextID().ToString().Replace("-", ""); _bookingOrderRepository.AsUpdateable(bookingOrder).UpdateColumns(it => new { it.TRUCKERID, it.TRUCKER, it.VERSION }).ExecuteCommand(); //这里直接调用订舱服务的功能,担心有异常所以这里单独做了异常捕获 try { //触发发送东胜 var syncDongshengRlt = await _bookingOrderService.SendBookingOrder(new long[] { bookingTruckInfo.BookingId.Value }); _logger.LogInformation($"推送订舱同步东胜完毕,id={bookingTruckInfo.BookingId.Value} rlt={JSON.Serialize(syncDongshengRlt)}"); } catch (Exception bkException) { _logger.LogInformation("批次={no} id={id} 触发发送东胜完成,原因:{erro}", batchNo, bookingTruckInfo.BookingId.Value, bkException.Message); } _logger.LogInformation("判断回写需要更新订舱的车队,更新完成"); } } } messageInfo.Main = bookingTruckSyncDto; if (bookingTruckInfo.TenantId.HasValue) messageInfo.Main.TenantId = bookingTruckInfo.TenantId.Value; var mqRlt = await PushSyncBookingTruckMQToDS6(messageInfo); _logger.LogInformation("发送MQ,rlt={rlt}", JSON.Serialize(mqRlt)); result.succ = true; result.msg = "保存成功"; result.ext = id; } catch (Exception ex) { result.succ = false; result.msg = ex.GetMessage("派车任务回写失败"); } return result; } /// /// 同步MQ推送派车信息到东胜6 /// /// 同步详情 /// 返回回执 private async Task PushSyncBookingTruckMQToDS6(BookingTruckSyncMessageInfo bookingTruckSyncMessageInfo) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var mqUrl = _cache.GetAllDictData().GetAwaiter().GetResult() .FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "BookingOrderMQUri")?.Value; if (mqUrl == null) { _logger.LogInformation("字典未配置 url_set->BookingOrderMQUri 请联系管理员"); throw Oops.Bah("字典未配置 url_set->BookingOrderMQUri 请联系管理员"); } //请求MQ var json = JSON.Serialize(bookingTruckSyncMessageInfo); var mqRlt = MQHelper.SendMQ(json, mqUrl, MQ_EXCHANGE_NAME, MQ_QUEUE_NAME , bookingTruckSyncMessageInfo.Main.TenantId); _logger.LogInformation("发送MQ请求完成,结果={rlt}", JSON.Serialize(mqRlt)); if (mqRlt.succ) { result.succ = true; result.msg = "同步东胜完成"; } else { result = mqRlt; } } catch (Exception ex) { result.succ = false; result.msg = ex.GetMessage("同步东胜失败"); } return result; } /// /// 获取场站数据 /// /// /// /// 返回场站详情 [HttpGet("/BookingTruck/GetYardData")] public async Task GetYardData(long bookingTruckId, bool isWeb = false) { //订舱派车数据 var entity = _bookingTruckRepository.AsQueryable().First(x => x.Id == bookingTruckId); if (entity == null) throw Oops.Oh($"派车信息不能为空", typeof(InvalidOperationException)); BookingOrder bookingOrder = null; if (entity.BookingId.HasValue) { bookingOrder = _bookingOrderRepository.AsQueryable().First(x => x.Id == entity.BookingId.Value); } string yardId = string.Empty; string mblNo = string.Empty; if (bookingOrder != null) { yardId = bookingOrder.YARDID; mblNo = bookingOrder.MBLNO; } if (string.IsNullOrWhiteSpace(yardId)) yardId = entity.YARDID; if (string.IsNullOrWhiteSpace(mblNo)) mblNo = entity.MBLNo; if (string.IsNullOrEmpty(yardId)) { throw Oops.Bah("场站信息不能为空"); } if (string.IsNullOrEmpty(mblNo)) { throw Oops.Bah("提单号不能为空"); } var rtn = await YardDataHelper.GetYardDataWithTranslateAsync(UserManager.UserId, bookingOrder.TenantId.Value, bookingOrder.TenantName, mblNo, yardId, isWeb); return rtn; } } }