using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Furion.DynamicApiController; using Furion.FriendlyException; using Mapster; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Myshipping.Application.Entity; using Myshipping.Application.Service.TaskManagePlat; using Myshipping.Core; using Myshipping.Core.Service; using MySqlX.XDevAPI.Common; using NPOI.XWPF.UserModel; using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Myshipping.Application { /// /// 预甩货通知 /// [ApiDescriptionSettings("Application", Name = "TaskManageRollingNomination", Order = 10)] public class TaskManageRollingNominationService : ITaskManageRollingNominationService, IDynamicApiController, ITransient { private readonly ISysCacheService _cache; private readonly ILogger _logger; private readonly SqlSugarRepository _taskBaseRepository; private readonly SqlSugarRepository _taskRollingNominationInfoRepository; private readonly SqlSugarRepository _taskRollingNominationShipInfoRepository; private readonly SqlSugarRepository _taskRollingNominationDetailInfoRepository; private readonly SqlSugarRepository _taskRollingNominationDispatchInfoRepository; private readonly SqlSugarRepository _taskShareLinkInfoRepository; private readonly SqlSugarRepository _bookingOrderRepository; private readonly SqlSugarRepository _bookingCtnRepository; private readonly INamedServiceProvider _namedServiceProvider; public TaskManageRollingNominationService(SqlSugarRepository taskBaseRepository, SqlSugarRepository taskRollingNominationInfoRepository, SqlSugarRepository taskRollingNominationDetailInfoRepository, SqlSugarRepository taskRollingNominationDispatchInfoRepository, SqlSugarRepository taskRollingNominationShipInfoRepository, SqlSugarRepository taskShareLinkInfoRepository, SqlSugarRepository bookingOrderRepository, INamedServiceProvider namedServiceProvider, SqlSugarRepository bookingCtnRepository, ISysCacheService cache, ILogger logger) { _taskBaseRepository = taskBaseRepository; _taskRollingNominationInfoRepository = taskRollingNominationInfoRepository; _taskRollingNominationDetailInfoRepository = taskRollingNominationDetailInfoRepository; _taskRollingNominationDispatchInfoRepository = taskRollingNominationDispatchInfoRepository; _taskRollingNominationShipInfoRepository = taskRollingNominationShipInfoRepository; _taskShareLinkInfoRepository = taskShareLinkInfoRepository; _bookingOrderRepository = bookingOrderRepository; _bookingCtnRepository = bookingCtnRepository; _namedServiceProvider = namedServiceProvider; _cache = cache; _logger = logger; } #region 获取预甩详情 /// /// 获取预甩详情 /// /// 预甩主键 /// 返回回执 [HttpGet("/TaskManageRollingNomination/GetInfo")] public async Task GetInfo(string pkId) { TaskRollingNominationShowDto model = null; try { var rollModel = _taskRollingNominationInfoRepository.AsQueryable() .First(a => a.PK_ID == pkId && !a.IsDeleted); if (rollModel == null) throw Oops.Oh($"预甩货主键{pkId}无法获取业务信息"); model = await InnerGetInfo(rollModel); } catch (Exception ex) { _logger.LogError($"获取预甩详情异常,原因:{ex.Message}"); throw ex; } return model; } #endregion #region 通过任务主键获取预甩详情 /// /// 通过任务主键获取预甩详情 /// /// 预甩任务主键 /// 返回回执 [HttpGet("/TaskManageRollingNomination/GetInfoByTaskId")] public async Task GetInfoByTaskId(string taskPkId) { TaskRollingNominationShowDto model = null; try { var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId && !a.IsDeleted); if (taskBase == null) throw Oops.Oh($"预甩货任务主键{taskPkId}无法获取任务信息"); var rollModel = _taskRollingNominationInfoRepository.AsQueryable() .First(a => a.TASK_ID == taskBase.PK_ID && !a.IsDeleted); if (rollModel == null) throw Oops.Oh($"预甩货任务主键{taskBase.PK_ID}无法获取业务信息"); model = await InnerGetInfo(rollModel); } catch(Exception ex) { _logger.LogError($"获取预甩详情异常,原因:{ex.Message}"); throw ex; } return model; } #endregion #region 获取预甩详情 /// /// 获取预甩详情 /// /// 预甩货详情实体类 /// 返回详情 private async Task InnerGetInfo(TaskRollingNominationInfo rollModel) { TaskRollingNominationShowDto model = null; try { List rollingPlanList = new List(); if (!string.IsNullOrWhiteSpace(rollModel.PLAN_TXT)) { rollingPlanList = rollModel.PLAN_TXT.Split("\\n").ToList(); } model = new TaskRollingNominationShowDto { PlanType = rollModel.PLAN_TYPE, CarrierId = rollModel.CARRIERID, Carrier = rollModel.CARRIER, ConfirmDeadLine = rollModel.CONFIRM_DEAD_LINE, CreateTime = rollModel.READ_CREATE_TIME, RollingTouchDoubleRollRemark = rollModel.ROLL_DOUBLE_REMARK, LoadDetailList = new List(), RollingPlanList = rollingPlanList, PreBillList = new List(), NominationId = rollModel.PK_ID }; var shipList = _taskRollingNominationShipInfoRepository.AsQueryable() .Where(a => a.NOM_ID == rollModel.PK_ID && a.IsDeleted == false).ToList(); var fromEntity = shipList.Where(a => a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)).ToList(); if (fromEntity.Count > 0) model.From = fromEntity.Select(p=>p.Adapt()).ToList(); var toEntity = shipList.Where(a => Regex.IsMatch(a.SHIP_TYPE,"To(\\s+[0-9]+)?" , RegexOptions.IgnoreCase)).ToList(); if (toEntity.Count > 0) model.To = toEntity.Select(p => p.Adapt()).ToList(); //这里为了前端原船和换船做了根据PORT对应 model.FromToList = model.From.GroupJoin(model.To, l => l.Port?.Trim(), r => r.Port?.Trim(), (l, r) => { TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto(); dto.FromShip = l; var currArg = r.ToList(); if (currArg.Count > 0) { dto.ToShipList = currArg.Select((p, idx) => { if (Regex.IsMatch(p.ShipType, "[0-9]+")) return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p }; return new { SortNo = idx + 1, Obj = p }; }).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList(); } return dto; }).ToList(); var withDispatchList = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true) .LeftJoin((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID) .Where((detail, dispatch) => detail.NOM_ID == rollModel.PK_ID && detail.IsDeleted == false && (string.IsNullOrWhiteSpace(dispatch.PK_ID) || (!string.IsNullOrWhiteSpace(dispatch.PK_ID) && dispatch.IsDeleted == false))) .Select((detail, dispatch) => new { Detail = detail, Dispatch = dispatch }).ToList(); List> tuples = new List>(); if (withDispatchList.Any(a => a.Detail.BOOKING_ID.HasValue && (a.Dispatch != null && !string.IsNullOrWhiteSpace(a.Dispatch.PK_ID)))) { model.PreBillList = withDispatchList.Where(a => a.Detail.BOOKING_ID.HasValue && (a.Dispatch != null && !string.IsNullOrWhiteSpace(a.Dispatch.PK_ID))) .GroupBy(a => a.Detail.CUSTOMERID) .SelectMany((a, idx) => { var cArg = a.ToList(); return a.GroupBy(b => b.Detail.SHIPMENT).Select( b => { var preBillArg = b.ToList(); var preBillDetail = preBillArg.FirstOrDefault().Detail; var preBillDispatch = preBillArg.FirstOrDefault().Dispatch; var cStaticlst = preBillArg.GroupBy(x => x.Detail.CTNALL) .Select(x => new { Key = x.Key, Num = x.Sum(t => t.Detail.CTNNUM) }).ToList(); string ctnStat = string.Join(",", cStaticlst.Select(x => $"{x.Key}*{x.Num}").ToArray()); cStaticlst.ForEach(y => tuples.Add(new Tuple(y.Key, y.Num))); string ctnNote = preBillArg.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.Detail.CTNNOTE))?.Detail.CTNNOTE; TaskRollingNominationShipPreBillShowDto preBillInfo = new TaskRollingNominationShipPreBillShowDto { Bookedby = preBillDetail.BOOKED_BY, ConfirmDate = preBillDispatch?.CONFIRM_DATE, ConfirmDeadLine = preBillDispatch?.CONFIRM_DEAD_LINE, CtnStat = ctnStat, CustomerId = preBillDetail.CUSTOMERID, CustomerName = preBillDetail.CUSTOMERNAME, ContractualName = preBillDetail.CONTRACTUAL_NAME, CreateShareLinkDate = preBillDispatch?.CREATE_SHARE_LINK_DATE, DischargePortName = preBillDetail.DISCHARGEPORT_NAME, IsSend = preBillDispatch != null ? preBillDispatch.IS_SEND : false, IsUserManual = preBillDispatch != null ? preBillDispatch.IS_USER_MANUAL : false, LoadPortName = preBillDetail.LOADPORT_NAME, PlaceOfDelivery = preBillDetail.PLACEOF_DELIVERY, PlaceOfReceipt = preBillDetail.PLACEOF_RECEIPT, Shipment = preBillDetail.SHIPMENT, Status = preBillDispatch?.STATUS, ShareLinkKey = preBillDispatch?.SHARE_LINK_KEY, UserOpinion = preBillDispatch?.USER_OPINION, UserOpinionTxt = preBillDispatch?.USER_OPINION_TXT, BatchId = preBillDispatch?.BATCH_ID, BookingId = preBillDetail.BOOKING_ID, GroupName = preBillDetail.CUSTOMERID.HasValue ? $"CUST_{idx + 1}" : "", CtnNote = ctnNote }; return preBillInfo; }).ToList(); }).ToList(); } if (withDispatchList.Any(a => (a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID) || !a.Detail.BOOKING_ID.HasValue) && !a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))) { model.PreBillList.AddRange(withDispatchList.Where(a => (a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID) || !a.Detail.BOOKING_ID.HasValue) && !a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase)) .GroupBy(a => a.Detail.SHIPMENT) .Select((b, idx) => { var preBillArg = b.ToList(); var preBillDetail = preBillArg.FirstOrDefault().Detail; var preBillDispatch = preBillArg.FirstOrDefault().Dispatch; var cStaticlst = preBillArg.GroupBy(x => x.Detail.CTNALL) .Select(x => new { Key = x.Key, Num = x.Sum(t => t.Detail.CTNNUM) }).ToList(); string ctnStat = string.Join(",", cStaticlst.Select(x => $"{x.Key}*{x.Num}").ToArray()); cStaticlst.ForEach(y => tuples.Add(new Tuple(y.Key, y.Num))); string ctnNote = preBillArg.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.Detail.CTNNOTE))?.Detail.CTNNOTE; TaskRollingNominationShipPreBillShowDto preBillInfo = new TaskRollingNominationShipPreBillShowDto { Bookedby = preBillDetail.BOOKED_BY, ConfirmDate = preBillDispatch?.CONFIRM_DATE, ConfirmDeadLine = preBillDispatch?.CONFIRM_DEAD_LINE, CtnStat = ctnStat, CustomerId = preBillDetail.CUSTOMERID, CustomerName = preBillDetail.CUSTOMERNAME, ContractualName = preBillDetail.CONTRACTUAL_NAME, CreateShareLinkDate = preBillDispatch?.CREATE_SHARE_LINK_DATE, DischargePortName = preBillDetail.DISCHARGEPORT_NAME, IsSend = preBillDispatch != null ? preBillDispatch.IS_SEND : false, IsUserManual = preBillDispatch != null ? preBillDispatch.IS_USER_MANUAL : false, LoadPortName = preBillDetail.LOADPORT_NAME, PlaceOfDelivery = preBillDetail.PLACEOF_DELIVERY, PlaceOfReceipt = preBillDetail.PLACEOF_RECEIPT, Shipment = preBillDetail.SHIPMENT, Status = preBillDispatch?.STATUS, ShareLinkKey = preBillDispatch?.SHARE_LINK_KEY, UserOpinion = preBillDispatch?.USER_OPINION, UserOpinionTxt = preBillDispatch?.USER_OPINION_TXT, BatchId = preBillDispatch?.BATCH_ID, BookingId = preBillDetail.BOOKING_ID, GroupName = $"SHIPMENT_{idx + 1}", CtnNote = ctnNote, EquipmentNumber = preBillDetail.EQUIPMENT_NUMBER }; return preBillInfo; }).ToList()); } if (withDispatchList.Any(a=>(a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID)) && a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))) { model.LoadDetailList = withDispatchList.Where(a => (a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID)) && a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase)) .Select(a => a.Detail.Adapt()).ToList(); } if(tuples.Count > 0) { model.TotalPreBillCtnStat = string.Join(",", tuples.GroupBy(x => x.Item1) .Select(x => $"{x.Key}*{x.Sum(t => t.Item2)}").ToArray()); } if (model.LoadDetailList.Count > 0) { model.TotalLoadCtnStat = string.Join(",", model.LoadDetailList.GroupBy(x => x.CtnAll) .Select(x => $"{x.Key}*{x.Sum(t => t.CtnNum)}").ToArray()); } } catch (Exception ex) { _logger.LogError($"获取预甩详情异常,原因:{ex.Message}"); throw ex; } return model; } #endregion #region 推送预甩货客户访问链接 /// /// 推送预甩货客户访问链接 /// /// 预甩货任务主键组 /// 返回回执 [HttpPost("/TaskManageRollingNomination/PushShareLink")] public async Task PushShareLink([FromBody] string[] nominationDispatchId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { } catch (Exception ex) { result.succ = false; result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}"; } return result; } #endregion #region 生成预甩货调度 /// /// 生成预甩货调度 /// /// 生成预甩货调度请求 /// 返回回执 [HttpPost("/TaskManageRollingNomination/DispatchRollingNomination")] public async Task DispatchRollingNomination([FromBody] RollingNominationDispatchRequestDto model) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { /* 1、如果调度ID不为空,标识选择新的明细替换原有的调度。 (1)首先匹配所选的箱型箱量是否一致,装货港、卸货港必需一致,不满足不能进行生成调度。 (2)删除原调度,生成新调度。 2、如果调度ID为空,标识是新增调度。 3、没有订舱ID或委托单位ID的数据不能生成调度。 */ DateTime nowDate = DateTime.Now; if (!model.isAdd) { if(string.IsNullOrWhiteSpace(model.nominationBatchId)) { throw Oops.Oh($"改配调度需要提供预甩货调度批次ID"); } if (model.loadDetailIds == null || model.loadDetailIds.Length == 0) { throw Oops.Oh($"预甩货可Load明细信息不能为空"); } var detailList = _taskRollingNominationDetailInfoRepository.AsQueryable() .Where(a => model.loadDetailIds.Contains(a.PK_ID) && a.IsDeleted == false).ToList(); if (detailList.Count != model.loadDetailIds.Length) { throw Oops.Oh($"预甩货明细部分获取失败,请重新获取预甩货明细"); } if (detailList.Any(a => !a.BOOKING_ID.HasValue || !a.CUSTOMERID.HasValue)) { throw Oops.Oh($"预甩货明细存在未对应订舱的记录,不能生成调度"); } var nomId = detailList.FirstOrDefault().NOM_ID; var nomModel = _taskRollingNominationInfoRepository.AsQueryable() .First(a => a.PK_ID == nomId); var shipmentList = detailList.Select(a => a.SHIPMENT).Distinct().ToList(); Dictionary batchDict = shipmentList.Select(a => new { Key = a, BatchId = IDGen.NextID().ToString() }) .ToDictionary(a => a.Key, b => b.BatchId); List dispatchList = new List(); List withDispatchDetailList = new List(); var withDispatchList = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true) .InnerJoin((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID) .Where((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID && detail.IsDeleted == false && dispatch.IsDeleted == false && dispatch.BATCH_ID == model.nominationBatchId) .Select((detail, dispatch) => new { Detail = detail, Dispatch = dispatch }).ToList(); if (withDispatchList.Count > 0) { withDispatchDetailList = withDispatchList.Select(a => a.Detail) .ToList(); } if (dispatchList.Count == 0) { throw Oops.Oh($"预甩货调度获取失败,无法改配"); } //如果原调度对应的明细含有本次提交的明细,不允许改配调度 if (withDispatchDetailList.Any(a => model.loadDetailIds.Any(b => b == a.PK_ID))) { throw Oops.Oh($"预甩货调度获取失败,提交明细已生成调度,无法改配"); } //需要匹配箱型箱量 var origCtnStat = string.Join(",", withDispatchDetailList .GroupBy(a => a.CTNALL).OrderBy(a => a.Key) .Select(a => $"{a.Key}*{a.Sum(b => b.CTNNUM)}").ToArray()); detailList = _taskRollingNominationDetailInfoRepository.AsQueryable() .Where(a => shipmentList.Contains(a.SHIPMENT) && a.IsDeleted == false && a.NOM_ID == nomId).ToList(); var targetCtnStat = string.Join(",", detailList .GroupBy(a => a.CTNALL).OrderBy(a => a.Key) .Select(a => $"{a.Key}*{a.Sum(b => b.CTNNUM)}").ToArray()); //如果箱型箱量不一致不能改配 if (!origCtnStat.Equals(targetCtnStat)) { throw Oops.Oh($"预甩货调度获取失败,提交明细箱型箱量于被改配调度不一致,无法改配"); } var origShip = withDispatchDetailList.FirstOrDefault(); var targetShip = detailList.FirstOrDefault(); var origKey = $"{origShip.PLACEOF_RECEIPT}_{origShip.LOADPORT_NAME}_{origShip.DISCHARGEPORT_NAME}_{origShip.PLACEOF_DELIVERY}"; var targeKey = $"{targetShip.PLACEOF_RECEIPT}_{targetShip.LOADPORT_NAME}_{targetShip.DISCHARGEPORT_NAME}_{targetShip.PLACEOF_DELIVERY}"; //收货地、装货港、卸货港、交货地必需一致 if (!origKey.Equals(targeKey)) { throw Oops.Oh($"预甩货调度获取失败,提交明细收货地、装货港、卸货港、交货地被改配调度不一致,无法改配"); } //删除原调度 withDispatchList.ForEach(async a => { a.Dispatch.IsDeleted = true; a.Dispatch.UpdatedTime = nowDate; a.Dispatch.UpdatedUserId = UserManager.UserId; a.Dispatch.UpdatedUserName = UserManager.Name; await _taskRollingNominationDispatchInfoRepository.AsUpdateable(a.Dispatch) .UpdateColumns(it => new { it.IsDeleted, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); }); //写入新调度 detailList.ForEach(a => { TaskRollingNominationDispatchInfo dispatchInfo = new TaskRollingNominationDispatchInfo { PK_ID = IDGen.NextID().ToString(), CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, DETAIL_ID = a.PK_ID, NOM_ID = a.NOM_ID, NOM_SHIP_ID = a.NOM_SHIP_ID, IsDeleted = false, STATUS = "WAIT", TASK_ID = nomModel.TASK_ID, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, BATCH_ID = batchDict[a.SHIPMENT], }; _taskRollingNominationDispatchInfoRepository.Insert(dispatchInfo); }); } else { var withDispatchList = _taskRollingNominationInfoRepository.AsQueryable().Filter(null, true) .InnerJoin((nom, detail) => nom.PK_ID == detail.NOM_ID) .LeftJoin((nom, detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID && dispatch.IsDeleted == false) .Where((nom, detail, dispatch) => detail.IsDeleted == false && detail.NOM_ID == model.nominationId) .Select((nom, detail, dispatch) => new { Nom = nom, Detail = detail, Dispatch = dispatch }).ToList(); if (withDispatchList.Any(p => p.Dispatch != null && !string.IsNullOrWhiteSpace(p.Dispatch.PK_ID))) { throw Oops.Oh($"预甩货明细已生成调度不能重复"); } var nomiInfo = withDispatchList.FirstOrDefault().Nom; var shipmentList = withDispatchList .Select(a => a.Detail.SHIPMENT) .Distinct().ToList(); Dictionary batchDict = shipmentList.Select(a => new { Key = a, BatchId = IDGen.NextID().ToString() }) .ToDictionary(a => a.Key, b => b.BatchId); DateTime deadLine = nomiInfo.CONFIRM_DEAD_LINE.Value.AddHours(2); //开始写入调度 withDispatchList.ForEach(info => { var a = info.Detail; if (!a.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase)) { TaskRollingNominationDispatchInfo dispatchInfo = new TaskRollingNominationDispatchInfo { PK_ID = IDGen.NextID().ToString(), CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, DETAIL_ID = a.PK_ID, NOM_ID = a.NOM_ID, NOM_SHIP_ID = a.NOM_SHIP_ID, IsDeleted = false, STATUS = RollingNominationDispatchStatusEnum.WAIT.ToString(), TASK_ID = nomiInfo.TASK_ID, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, BATCH_ID = batchDict[a.SHIPMENT], CONFIRM_DEAD_LINE = deadLine }; _taskRollingNominationDispatchInfoRepository.Insert(dispatchInfo); } }); } result.succ = true; result.msg = "成功"; } catch (Exception ex) { result.succ = false; result.msg = $"生成预甩货调度异常,原因:{ex.Message}"; } return result; } #endregion #region 刷新预甩货对应订舱 /// /// 刷新预甩货对应订舱 /// /// 预甩货主键 /// 返回回执 [HttpGet("/TaskManageRollingNomination/RefreshBookingOrder")] public async Task RefreshBookingOrder(string nominationId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { /* 获取所有当票预甩的所有没有BOOKING_ID的明细记录,并用SHIPMENT(提单号),检索订舱数据,能匹配的更新 */ var list = _taskRollingNominationInfoRepository.AsQueryable().Filter(null, true) .InnerJoin((nom, detail) => nom.PK_ID == detail.NOM_ID) .Where((nom, detail) => nom.PK_ID == nominationId && detail.IsDeleted == false && !detail.BOOKING_ID.HasValue) .Select((nom, detail) => detail).ToList(); if (list.Count > 0) { var mblNoArg = list.Select(a=>a.SHIPMENT).Distinct().ToList(); var orderList = _bookingOrderRepository.AsQueryable() .Where(a => mblNoArg.Contains(a.MBLNO) && !a.ParentId.HasValue && a.IsDeleted == false).ToList(); DateTime nowDate = DateTime.Now; if (orderList.Count > 0) { orderList.ForEach(ord => { var dlist = list.Where(b => b.SHIPMENT.Equals(ord.MBLNO)).ToList(); if (dlist.Count > 0) { dlist.ForEach(dt => { dt.BOOKING_ID = ord.Id; dt.UpdatedTime = nowDate; dt.UpdatedUserId = UserManager.UserId; dt.UpdatedUserName = UserManager.Name; _taskRollingNominationDetailInfoRepository.AsUpdateable(dt) .UpdateColumns(it => new { it.BOOKING_ID, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommand(); }); } }); } } } catch (Exception ex) { result.succ = false; result.msg = $"刷新预甩货对应订舱异常,原因:{ex.Message}"; } return result; } #endregion #region 查看分享链接 /// /// 查看分享链接 /// /// 预甩调度批次号 /// 返回回执 [HttpGet("/TaskManageRollingNomination/GetUrl")] public async Task GetUrl(string dispatchBatchId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { /* 用预甩调度的dispatchBatchId关联分享表的BUSI_ID获取分享KEY */ if (string.IsNullOrWhiteSpace(dispatchBatchId)) throw Oops.Oh($"预甩调度批次号不能为空"); var dispatchInfo = _taskRollingNominationDispatchInfoRepository.AsQueryable() .First(a => a.BATCH_ID == dispatchBatchId); if (dispatchInfo == null) { throw Oops.Oh($"获取预甩调度信息失败,不存在或已作废"); } if(string.IsNullOrWhiteSpace(dispatchInfo.SHARE_LINK_KEY)) throw Oops.Oh($"链接访问KEY不存在,请生成分享链接"); string[] statusArg = new string[] { RollingNominationDispatchStatusEnum.CANCEL.ToString(), RollingNominationDispatchStatusEnum.EXPIRE.ToString() }; if (statusArg.Any(a => a.Equals(dispatchInfo.STATUS, StringComparison.OrdinalIgnoreCase))) throw Oops.Oh($"链接访问KEY状态不可用"); result.succ = true; result.ext = dispatchInfo.SHARE_LINK_KEY; } catch (Exception ex) { result.succ = false; result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}"; } return result; } #endregion #region 获取Status是load的可配载的列表 /// /// 获取Status是load的可配载的列表 /// /// 预甩货任务主键 /// 返回回执 [HttpGet("/TaskManageRollingNomination/GetLoadStatusDetailList")] public async Task GetLoadStatusDetailList(string taskPkId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var withDispatchList = _taskRollingNominationInfoRepository.AsQueryable().Filter(null, true) .InnerJoin((nom,detail)=> nom.PK_ID == detail.NOM_ID) .LeftJoin((nom,detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID && dispatch.IsDeleted == false) .Where((nom,detail, dispatch) => nom.TASK_ID == taskPkId && detail.IsDeleted == false && string.IsNullOrWhiteSpace(dispatch.TASK_ID)) .Select((nom, detail, dispatch) => new { Detail = detail}).ToList(); if (withDispatchList.Count > 0) { result.ext = withDispatchList.Select(a => a.Detail.Adapt()).ToList(); } result.succ = true; } catch (Exception ex) { result.succ = false; result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}"; } return result; } #endregion #region 获取提单号下预甩货的单票明细 /// /// 获取提单号下预甩货的单票明细 /// /// 预甩货主键 /// 提单号 /// 返回回执 [HttpGet("/TaskManageRollingNomination/GetPreBillDetailList")] public async Task GetPreBillDetailList([FromQuery] string nominationId, [FromQuery] string shipmentNo) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var withDispatchList = _taskRollingNominationInfoRepository.AsQueryable() .InnerJoin((nom, detail) => nom.PK_ID == detail.NOM_ID) .Where((nom, detail) => nom.PK_ID == nominationId && detail.IsDeleted == false && detail.SHIPMENT == shipmentNo) .Select((nom, detail) => new { Detail = detail }).ToList(); if (withDispatchList.Count > 0) { result.ext = withDispatchList.Select(a => a.Detail.Adapt()).ToList(); } result.succ = true; } catch (Exception ex) { result.succ = false; result.msg = $"获取提单号下预甩货的单票明细异常,原因:{ex.Message}"; } return result; } #endregion #region 保存预甩货明细箱型信息 /// /// 保存预甩货明细箱型信息(处理没有给箱型高度或者未能翻译的箱型,进行人工修正) /// /// 保存预甩货明细箱型请求 /// 返回回执 [HttpPost("/TaskManageRollingNomination/SaveDetailContainer")] public async Task SaveDetailContainer(SaveDetailContainerDto model) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { if (string.IsNullOrWhiteSpace(model.ctnCode)) { throw Oops.Oh($"请求的箱型代码不能为空"); } var detailInfo = _taskRollingNominationDetailInfoRepository.AsQueryable() .First(a => a.PK_ID == model.detailPKId && a.IsDeleted == false); if (detailInfo == null) throw Oops.Oh($"预甩货明细主键{model.detailPKId}无法获取业务信息"); var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList(); var ctnCodeModel = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) && a.Code.Equals(model.ctnCode, StringComparison.OrdinalIgnoreCase)); if (ctnCodeModel == null) throw Oops.Oh($"请求的箱型代码基础数据不存在,请修改"); detailInfo.CTNCODE = ctnCodeModel.Code; detailInfo.CTNALL = ctnCodeModel.Name; detailInfo.UpdatedTime = DateTime.Now; detailInfo.UpdatedUserId = UserManager.UserId; detailInfo.UpdatedUserName = UserManager.Name; await _taskRollingNominationDetailInfoRepository.AsUpdateable(detailInfo).UpdateColumns(it => new { it.CTNCODE, it.CTNALL, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); result.succ = true; result.msg = "成功"; } catch (Exception ex) { result.succ = false; result.msg = $"保存预甩货明细箱型信息异常,原因:{ex.Message}"; } return result; } #endregion #region 生成访问链接 /// /// 生成访问链接 /// /// 创建分享链接请求 /// 返回回执 [HttpPost("/TaskManageRollingNomination/GenShareLink")] public async Task GenShareLink(RollingNominationGenShareLinkDto model) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { if (string.IsNullOrWhiteSpace(model.dispatchBatchId)) { throw Oops.Oh($"预甩调度批次ID不能为空"); } var list = _taskRollingNominationDispatchInfoRepository.AsQueryable() .Where(a => a.BATCH_ID == model.dispatchBatchId).ToList(); if(list.Count == 0) throw Oops.Oh($"预甩调度批次ID无法获取业务信息"); var taskInfo = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == list.FirstOrDefault().TASK_ID); ShareLinkRequestDto reqDto = new ShareLinkRequestDto { businessId = model.dispatchBatchId, businessType = "NOMI_DISPATCH", expireDate = list.FirstOrDefault().CONFIRM_DEAD_LINE.Value.ToString("yyyy-MM-dd HH:mm:ss"), isUserFeedBack = true, taskType = taskInfo.TASK_BASE_TYPE, isRenew = model.isRenew }; var service = _namedServiceProvider.GetService(nameof(TaskManageShareLinkService)); result = await service.CreateShareLink(reqDto); if(result.succ) { DateTime nowDate = DateTime.Now; string shareKey = result.ext.ToString(); list.ForEach(p => { p.SHARE_LINK_KEY = shareKey; p.CREATE_SHARE_LINK_DATE = nowDate; p.UpdatedTime = nowDate; p.UpdatedUserId = UserManager.UserId; p.UpdatedUserName = UserManager.Name; _taskRollingNominationDispatchInfoRepository.AsUpdateable(p) .UpdateColumns(it => new { it.SHARE_LINK_KEY, it.CREATE_SHARE_LINK_DATE, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); }); } } catch(Exception ex) { result.succ = false; result.msg = $"生成访问链接异常,原因:{ex.Message}"; } return result; } #endregion #region 取消访问链接 /// /// 取消访问链接 /// /// 预甩调度批次ID /// 返回回执 [HttpPost("/TaskManageRollingNomination/CancelShareLink")] public async Task CancelShareLink(string dispatchBatchId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { if (string.IsNullOrWhiteSpace(dispatchBatchId)) { throw Oops.Oh($"预甩调度批次ID不能为空"); } var list = _taskRollingNominationDispatchInfoRepository.AsQueryable() .Where(a => a.BATCH_ID == dispatchBatchId).ToList(); if (list.Count == 0) throw Oops.Oh($"预甩调度批次ID无法获取业务信息"); var service = _namedServiceProvider.GetService(nameof(TaskManageShareLinkService)); result = await service.CancelShareLink(dispatchBatchId); } catch (Exception ex) { result.succ = false; result.msg = $"取消访问链接异常,原因:{ex.Message}"; } return result; } #endregion #region 获取用户反馈信息 /// /// 获取用户反馈信息 /// /// 预甩调度批次ID /// 返回回执 [HttpPost("/TaskManageRollingNomination/GetUserFeedBack")] public async Task GetUserFeedBack(string dispatchBatchId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { if (string.IsNullOrWhiteSpace(dispatchBatchId)) { throw Oops.Oh($"预甩调度批次ID不能为空"); } var list = _taskRollingNominationDispatchInfoRepository.AsQueryable() .Where(a => a.BATCH_ID == dispatchBatchId).ToList(); if (list.Count == 0) throw Oops.Oh($"预甩调度批次ID无法获取业务信息"); result.succ = true; result.ext = new { userOpinion = list.FirstOrDefault().USER_OPINION, userOpinionTxt = list.FirstOrDefault().USER_OPINION_TXT }; } catch (Exception ex) { result.succ = false; result.msg = $"获取用户反馈信息异常,原因:{ex.Message}"; } return result; } #endregion } }