using Amazon.Runtime.Internal.Util; using DS.Module.Core; using DS.Module.Core.Log; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Entity; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Mapster; using Microsoft.AspNetCore.Mvc; using DS.WMS.Core.Op.Interface; using SqlSugar.IOC; using Newtonsoft.Json; using NLog; using DS.WMS.Core.Sys.Interface; namespace DS.WMS.Core.Op.Method { public class BookingSlotService //: IBookingSlotService { private readonly IServiceProvider _serviceProvider; private readonly ISqlSugarClient db; private readonly IUser user; private readonly ISaasDbService saasService; private readonly ISeaExportService _seaExportService; private readonly IBookingLabelService _bookingLabelService; private readonly ILogAuditService _logAuditService; private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger(); public BookingSlotService(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; db = _serviceProvider.GetRequiredService(); user = _serviceProvider.GetRequiredService(); saasService = _serviceProvider.GetRequiredService(); _seaExportService = _serviceProvider.GetRequiredService(); _bookingLabelService = _serviceProvider.GetRequiredService(); _logAuditService = _serviceProvider.GetRequiredService(); } #region 保存舱位 /// /// 保存舱位 /// /// 舱位详情 /// 返回输出 public async Task> Save(BookingSlotBaseSaveInput input) { BookingSlotBase model = null; var tenantDb = saasService.GetBizDbScopeById(user.TenantId); if (input.Id > 0) //修改 { var c = tenantDb.Queryable().Where(x => x.SlotBookingNo == input.SlotBookingNo && input.Id != input.Id).Count(); if (c > 0) { //订舱提单号已存在 throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotSlotBookingNoExists))); } model = tenantDb.Queryable().First(x => x.Id == input.Id); var oldObj = model.Adapt(); input.Adapt(model); // 1.判断新的舱位信息的7个库存统计维度是否发生变化 // 2.如果有变化,则需要更新旧的库存信息 bool isNeedUpdateOldStock = false; if (oldObj.Vessel != model.Vessel || oldObj.Voyno != model.Voyno || oldObj.BookingSlotType != model.BookingSlotType || oldObj.CarrierCode != model.CarrierCode || oldObj.PortLoadId != model.PortLoadId || oldObj.PortDischargeId != model.PortDischargeId) { isNeedUpdateOldStock = true; } await tenantDb.Updateable(model).ExecuteCommandAsync(); if (isNeedUpdateOldStock) { //更新库存 //await _publisher.PublishAsync(new ChannelEventSource("BookingSlotStock:Update", new BookingSlotStockUpdateModel //{ // BOOKING_SLOT_TYPE = oldObj.BOOKING_SLOT_TYPE, // CARRIERID = oldObj.CARRIERID, // CONTRACT_NO = oldObj.CONTRACT_NO, // VESSEL = oldObj.VESSEL, // VOYNO = oldObj.VOYNO, // PORTLOADID = oldObj.PORTLOADID, // PORTDISCHARGEID = oldObj.PORTDISCHARGEID, // TenantId = model.TenantId //})); } var delCtnList = tenantDb.Queryable().Where(x => x.SlotId == model.Id).ToList(); if(delCtnList.Count > 0) await tenantDb.Deleteable(delCtnList).ExecuteCommandAsync(); if (input.CtnList != null) { foreach (var ctn in input.CtnList) { var newCtn = ctn.Adapt(); newCtn.SlotId = model.Id; await tenantDb.Insertable(newCtn).ExecuteCommandAsync(); } } #region 关联订舱信息修改 if (input.BookingSlotSaleInfoList != null) { foreach (var item in input.BookingSlotSaleInfoList) { if (!item.UpdateFlag) { continue; } var allocation = await tenantDb.Queryable().FirstAsync(x => x.Id == item.Id); if (allocation == null) { //保存失败,原因:更新关联订舱时未查询到订舱(关联表Id:{item.Id}) throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotSaveFailAllocRecordNull)), item.Id)); } // 更新关联表 item.Adapt(allocation); await tenantDb.Ado.BeginTranAsync(); try { await tenantDb.Updateable(allocation).UpdateColumns(x => new { x.CustomerId, x.CustomerName, x.CustServiceId, x.CustService, x.Sale, x.SaleId, x.Op, x.OpId, x.Doc, x.DocId, x.BusinessId, x.Business, x.Shipper, x.SaleTime, x.GoodsName, x.SellingPrice, x.UpdateBy, //x.UpdatedUserName, x.UpdateTime, }).ExecuteCommandAsync(); // 更新订舱表 //var bookingOrder = await _repBookingOrder.FirstOrDefaultAsync(x => x.Id == allocation.BOOKING_ID); var bookingOrder = _seaExportService.GetSeaExportInfo(allocation.BookingId.ToString()).Data; /* var oldBookingOrder = bookingOrder.Adapt(); if (bookingOrder != null) { bookingOrder.CUSTOMERID = allocation.CUSTOMERID; bookingOrder.CUSTOMERNAME = allocation.CUSTOMERNAME; bookingOrder.CUSTSERVICE = allocation.CUSTSERVICE; bookingOrder.CUSTSERVICEID = allocation.CUSTSERVICEID; bookingOrder.SALE = allocation.SALE; bookingOrder.SALEID = allocation.SALEID; bookingOrder.OP = allocation.OP; bookingOrder.OPID = allocation.OPID; bookingOrder.DOC = allocation.DOC; bookingOrder.DOCID = allocation.DOCID; bookingOrder.BUSINESS = allocation.BUSINESS; bookingOrder.BUSINESSID = allocation.BUSINESSID; await _repBookingOrder.AsUpdateable(bookingOrder).UpdateColumns(x => new { x.CUSTOMERID, x.CUSTOMERNAME, x.CUSTSERVICE, x.CUSTSERVICEID, x.SALE, x.SALEID, x.OP, x.OPID, x.DOC, x.DOCID, x.UpdatedUserId, x.UpdatedUserName, x.UpdatedTime, }).ExecuteCommandAsync(); Parallel.For(0, 1, (n) => { //bookingOrderService.SaveLog(bookingOrder, oldBookingOrder, "舱位关联更新"); // 推送东胜 //bookingOrderService.SendBookingOrder(new long[] { allocation.BOOKING_ID }); }); } */ await tenantDb.Ado.CommitTranAsync(); } catch (Exception) { await tenantDb.Ado.RollbackTranAsync(); //await ex.LogAsync(Db); //return DataResult.Failed(MultiLanguageConst.Operation_Failed); //_repAllocation.CurrentRollbackTran(); throw; } } } #endregion //Parallel.For(0, 1, (n) => //{ // _ = InsLog("Update", model.Id, typeof(BookingSlotBaseSaveInput), oldObj, input, // nameof(BookingSlotBaseApiSaveDto.CtnList), // nameof(BookingSlotBaseApiSaveDto.BookingSlotSaleInfoList)); //}); } else { var c = tenantDb.Queryable().Where(x => x.SlotBookingNo == input.SlotBookingNo).Count(); if (c > 0) { //订舱提单号已存在 throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotSlotBookingNoExists))); } model = input.Adapt(); await tenantDb.Insertable(model).ExecuteReturnEntityAsync(); foreach (var ctn in input.CtnList) { var newCtn = ctn.Adapt(); newCtn.SlotId = model.Id; await tenantDb.Insertable(newCtn).ExecuteCommandAsync(); } //await InsLog("Add", model.Id, "新增舱位"); } //更新库存 //await _publisher.PublishAsync(new ChannelEventSource("BookingSlotStock:Update", new BookingSlotStockUpdateModel //{ // BOOKING_SLOT_TYPE = model.BOOKING_SLOT_TYPE, // CARRIERID = model.CARRIERID, // CONTRACT_NO = model.CONTRACT_NO, // VESSEL = model.VESSEL, // VOYNO = model.VOYNO, // PORTLOADID = model.PORTLOADID, // PORTDISCHARGEID = model.PORTDISCHARGEID, // TenantId = model.TenantId //})); var inputDto = new BookingSlotBaseApiDto { DataObj = new BookingSlotBaseApiSaveDto { PortDischargeId = model.PortDischargeId, PortDischarge = model.PortDischarge, PortLoadId = model.PortLoadId, PortLoad = model.PortLoad, PlaceDelivery = model.PlaceDelivery, PlaceDeliveryId = model.PlaceDeliveryId, PlaceReceipt = model.PlaceReceipt, PlaceReceiptId = model.PlaceReceiptId, } }; //这里自动匹配标签 await GenerateSlotLabel(inputDto, model.Id); return await Detail(model.Id); } #endregion #region 自动生成舱位标签 /// /// 自动生成舱位标签 /// /// 舱位详情 /// 舱位ID /// private async Task> GenerateSlotLabel(BookingSlotBaseApiDto dto, long id) { try { /* 1、获取所有的可用标签 2、只执行REGEX_PATTERN_TXT有值的标签记录。 3、根据提取的标签JSON执行验证,符合条件的自动标记本标签 */ var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var labelList = _bookingLabelService.List(1).GetAwaiter().GetResult().Data; List ruleList = new List(); if (labelList.Count > 0) { for (int i = 0; i < labelList.Count; i++) { if (!string.IsNullOrWhiteSpace(labelList[i].RegexPatternTxt)) { try { var regList = JsonConvert.DeserializeObject>(labelList[i].RegexPatternTxt); if (regList != null && regList.Count > 0) { bool isSucc = true; for (int j = 0; j < regList.Count; j++) { var operEnum = (LabelRegexOperEnum)System.Enum.Parse(typeof(LabelRegexOperEnum), regList[j].oper); if (regList[j].name.Equals("PORTLOADID", StringComparison.OrdinalIgnoreCase)) { isSucc = CheckLabel("PORTLOADID", dto.DataObj.PortLoadId, regList[j].val, regList[j].master, operEnum); if (isSucc) { ruleList.Add(labelList[i]); break; } else { if (regList[j].master) break; continue; } } else if (regList[j].name.Equals("PLACERECEIPT", StringComparison.OrdinalIgnoreCase)) { isSucc = CheckLabel("PLACERECEIPT", dto.DataObj.PlaceReceipt, regList[j].val, regList[j].master, operEnum); if (isSucc) { ruleList.Add(labelList[i]); break; } else { if (regList[j].master) break; continue; } } else if (regList[j].name.Equals("PORTLOAD", StringComparison.OrdinalIgnoreCase)) { isSucc = CheckLabel("PORTLOAD", dto.DataObj.PortLoad, regList[j].val, regList[j].master, operEnum); if (isSucc) { ruleList.Add(labelList[i]); break; } else { if (regList[j].master) break; continue; } } else if (regList[j].name.Equals("PORTDISCHARGEID", StringComparison.OrdinalIgnoreCase)) { isSucc = CheckLabel("PORTDISCHARGEID", dto.DataObj.PortDischargeId, regList[j].val, regList[j].master, operEnum); if (isSucc) { ruleList.Add(labelList[i]); break; } else { if (regList[j].master) break; continue; } } else if (regList[j].name.Equals("PORTDISCHARGE", StringComparison.OrdinalIgnoreCase)) { isSucc = CheckLabel("PORTDISCHARGE", dto.DataObj.PortDischarge, regList[j].val, regList[j].master, operEnum); if (isSucc) { ruleList.Add(labelList[i]); break; } else { if (regList[j].master) break; continue; } } else if (regList[j].name.Equals("PLACEDELIVERY", StringComparison.OrdinalIgnoreCase)) { isSucc = CheckLabel("PLACEDELIVERY", dto.DataObj.PlaceDelivery, regList[j].val, regList[j].master, operEnum); if (isSucc) { ruleList.Add(labelList[i]); break; } else { if (regList[j].master) break; continue; } } } if (isSucc) { Logger.Log(NLog.LogLevel.Info, $"标签对应到有效规则,{labelList[i].Name}"); } } } catch (Exception innEx) { Logger.Log(NLog.LogLevel.Info, $"标签对应失败,{labelList[i].Name},原因:{innEx.Message}"); } } else { continue; } } if (ruleList.Count > 0) { var bindModel = new BindLabelDto { BusinessIdArray = new[] { id }, LabelIdArray = ruleList.Select(a => a.Id.Value).ToArray() }; Logger.Log(NLog.LogLevel.Info, $"标签绑定请求,{JsonConvert.SerializeObject(bindModel)}"); await _bookingLabelService.SetLabel(bindModel); Logger.Log(NLog.LogLevel.Info, $"标签绑定请求完成"); } } } catch (Exception e) { Logger.Log(NLog.LogLevel.Error, $"自动生成舱位标签失败,原因:{e.Message}"); return DataResult.Failed(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotSlotBookingNoExists)),e.Message)); } return DataResult.Success(string.Empty); } #endregion #region 判断标签识别 /// /// 判断标签识别 /// /// 字段名称 /// 字段值 /// 判断值 /// 是否必校验 /// 操作符枚举 /// true-满足识别 false-不满足识别 private bool CheckLabel(string name, string val, string checkVal, bool isMaster, LabelRegexOperEnum operEnum) { if (operEnum == LabelRegexOperEnum.equal) { if (!string.IsNullOrWhiteSpace(val) && val.Equals(checkVal, StringComparison.OrdinalIgnoreCase)) { return true; } } else if (operEnum == LabelRegexOperEnum.startwith) { if (!string.IsNullOrWhiteSpace(val) && val.StartsWith(checkVal, StringComparison.OrdinalIgnoreCase)) { return true; } } else if (operEnum == LabelRegexOperEnum.like) { if (!string.IsNullOrWhiteSpace(val) && val.Contains(checkVal, StringComparison.OrdinalIgnoreCase)) { return true; } } else if (operEnum == LabelRegexOperEnum.notequal) { if (!string.IsNullOrWhiteSpace(val)) { if (!val.Equals(checkVal, StringComparison.OrdinalIgnoreCase)) { return true; } else { if (isMaster) return false; } } } else if (operEnum == LabelRegexOperEnum.notexists) { if (!string.IsNullOrWhiteSpace(val)) { if (!val.Contains(checkVal, StringComparison.OrdinalIgnoreCase)) { return true; } else { if (isMaster) return false; } } } else if (operEnum == LabelRegexOperEnum.notstartwith) { if (!string.IsNullOrWhiteSpace(val)) { if (!val.StartsWith(checkVal, StringComparison.OrdinalIgnoreCase)) { return true; } else { if (isMaster) return false; } } } return false; } #endregion #region 获取舱位详情 /// /// 获取舱位详情 /// /// 舱位主键 /// 返回舱位详情 public async Task> Detail(long id) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var slotBase = await tenantDb.Queryable().FirstAsync(u => u.Id == id); if (slotBase == null) { //未查询到此舱位信息,已删除或不存在 throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotBaseInfoNull))); } var ctns = await tenantDb.Queryable().Where(x => x.SlotId == id).ToListAsync(); var rtn = slotBase.Adapt(); rtn.CtnList = ctns.Adapt>(); rtn.LogList = _logAuditService.GetAuditLogBookingList(slotBase.Id).GetAwaiter().GetResult()?.Data; // 赋值关联的订舱列表 // 查询舱位绑定的销售信息,赋值到舱位对象中 List saleInfoList = await tenantDb.Queryable() .Where(x => x.BookingSlotId == id) .Select(x => new BookingSlotSaleInfoDto { Id = x.Id, BookingId = x.BookingId, BookingSlotId = x.BookingSlotId, CustomerId = x.CustomerId, CustomerName = x.CustomerName, CustServiceId = x.CustServiceId, CustService = x.CustService, SaleId = x.SaleId, Sale = x.Sale, OpId = x.OpId, Op = x.Op, DocId = x.DocId, Doc = x.Doc, BusinessId = x.BusinessId, Business = x.Business, SaleTime = x.SaleTime, Shipper = x.Shipper, GoodsName = x.GoodsName, SellingPrice = x.SellingPrice, CreatedUserId = x.CreateBy }).ToListAsync(); /* if (saleInfoList.Any()) { // 判断是否启用了委托单位查看控制权限 var tenantParamList = await _cache.GetAllTenantParam(); var isEnableCustomerAuthority = tenantParamList.FirstOrDefault(x => x.TenantId == UserManager.TENANT_ID && x.ParaCode == TenantParamCode.IS_ENABLE_CUSTOMER_AUTHORITY)?.ItemCode == "YES"; List userList = null; List userListStr = null; if (isEnableCustomerAuthority) { userList = await _sysDataUserMenuService.GetDataScopeList(MenuConst.MenuDjyCustomer); if (userList != null && userList.Count > 0) { userListStr = userList.Select(x => x.ToString()).ToList(); // 遍历销售信息,如果销售信息中的“销售、操作、单证、客服、创建人”中不在当前登陆人的权限范围,则隐藏客户信息 foreach (BookingSlotSaleInfoDto saleInfoItem in saleInfoList) { if (!userList.Contains(saleInfoItem.CreatedUserId ?? 0) && !userListStr.Contains(saleInfoItem.OPID) && !userListStr.Contains(saleInfoItem.DOCID) && !userListStr.Contains(saleInfoItem.SALEID) && !userListStr.Contains(saleInfoItem.CUSTSERVICEID)) { saleInfoItem.CUSTOMERID = 0; saleInfoItem.CUSTOMERNAME = "--"; saleInfoItem.OPID = ""; saleInfoItem.OP = "--"; saleInfoItem.DOCID = ""; saleInfoItem.DOC = "--"; saleInfoItem.SALEID = ""; saleInfoItem.SALE = "--"; saleInfoItem.SHIPPER = "--"; saleInfoItem.GOODSNAME = "--"; saleInfoItem.CUSTSERVICEID = ""; saleInfoItem.CUSTSERVICE = "--"; } } } } } */ rtn.BookingSlotSaleInfoList = saleInfoList; return DataResult.Success(rtn); } #endregion } }