using DS.Module.Core; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Interface; using DS.WMS.Core.Sys.Interface; using DS.WMS.Core.TaskPlat.Dtos; using DS.WMS.Core.TaskPlat.Entity; using DS.WMS.Core.TaskPlat.Interface; using LanguageExt.Common; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; using NLog; using NPOI.SS.Formula.Functions; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Mapster; using DS.Module.DjyServiceStatus; using DS.WMS.Core.Op.Entity; using Microsoft.AspNetCore.Mvc; using NPOI.HPSF; using DS.WMS.Core.Invoice.Dtos; using DS.WMS.Core.Op.Method; using DS.WMS.Core.Code.Interface; using DS.WMS.Core.Map.Interface; using LanguageExt; using Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments; using Newtonsoft.Json; using System.Net.Http.Headers; namespace DS.WMS.Core.TaskPlat.Method { public class TaskManageSISubmittedService: ITaskManageSISubmittedService { private readonly IServiceProvider _serviceProvider; private readonly ISqlSugarClient db; private readonly IUser user; private readonly ISaasDbService saasService; private readonly ISeaExportService _seaExportService; private readonly IConfigService _configService; private readonly IUserService _userService; private readonly IDjyServiceStatusService _djyServiceStatusService; private readonly ITaskManageBaseService _taskManageBaseService; private readonly ISysFileService _sysFileService; private readonly IOpFileService _opFileService; private readonly ISeaExportCommonService _seaExportCommonService; private readonly ICodeIssueTypeService _codeIssueTypeService; private readonly IMappingIssueTypeService _mappingIssueTypeService; //租户SI回执是否自动更新订舱 const string CONST_SI_SUBMITTED_DEFAULT_PARAM = "SI_SUBMITTED_AUTO_UPDATE_ORDER"; private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger(); public TaskManageSISubmittedService(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; db = _serviceProvider.GetRequiredService(); user = _serviceProvider.GetRequiredService(); saasService = _serviceProvider.GetRequiredService(); _seaExportService = _serviceProvider.GetRequiredService(); _configService = _serviceProvider.GetRequiredService(); _userService = _serviceProvider.GetRequiredService(); _djyServiceStatusService = _serviceProvider.GetRequiredService(); _taskManageBaseService = _serviceProvider.GetRequiredService(); _opFileService = _serviceProvider.GetRequiredService(); _sysFileService = _serviceProvider.GetRequiredService(); _seaExportCommonService = _serviceProvider.GetRequiredService(); _codeIssueTypeService = _serviceProvider.GetRequiredService(); _mappingIssueTypeService = _serviceProvider.GetRequiredService(); } #region 通过任务主键获取截单回执详情 /// /// 通过任务主键获取截单回执详情 /// /// 截单回执任务主键 /// 返回回执 public async Task> GetInfoByTaskId(long taskPKId) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var queryList = await tenantDb.Queryable() .InnerJoin((a, b) => a.Id == b.TASK_ID) .Where((a, b) => a.Id == taskPKId) .Select((a, b) => new { Base = a, SI = b }) .ToListAsync(); //任务主键{taskPkId}无法获取业务信息 if (queryList.Count == 0) throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId)); var siSubmitted = queryList.FirstOrDefault().SI; var taskBase = queryList.FirstOrDefault().Base; var dto = siSubmitted.Adapt(); if (dto != null) { dto.IsComplete = taskBase.IS_COMPLETE == 1 ? true : false; dto.CompleteTime = taskBase.COMPLETE_DATE; } return DataResult.Success(dto); } #endregion #region 检索对应的订舱订单并保存订舱ID /// /// 检索对应的订舱订单并保存订舱ID /// /// 截单回执任务主键 /// 返回回执 public async Task> SearchAndMarkBookingOrder(long taskPKId) { SeaExportOrderExtension orderInfo = null; try { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var queryList = await tenantDb.Queryable() .InnerJoin((a, b) => a.Id == b.TASK_ID) .Where((a, b) => a.Id == taskPKId) .Select((a, b) => new { Base = a, SI = b }) .ToListAsync(); //任务主键{taskPkId}无法获取业务信息 if (queryList.Count == 0) throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId)); string mblNo = queryList.FirstOrDefault().Base.MBL_NO; var orderRlt = await _seaExportService.SearchOrderInfo(mblNo); if (!orderRlt.Succeeded) { // 提单号 {0} 检索海运出口订单失败 throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseSearchOrderFailMBLNo)), mblNo)); } orderInfo = orderRlt.Data; foreach (var item in queryList.Select(a => a.SI).ToList()) { item.BOOKING_ID = orderInfo.currOrder.Id; item.UpdateTime = DateTime.Now; item.UpdateBy = long.Parse(user.UserId); item.UpdateUserName = user.UserName; tenantDb.Updateable(item).UpdateColumns(x => new { x.BOOKING_ID, x.UpdateTime, x.UpdateBy, x.UpdateUserName }).ExecuteCommand(); var list = tenantDb.Queryable().Where(a => a.P_ID == item.Id).ToList(); if (list != null && list.Count > 0) { list.ForEach(async p => { if (p.MBL_NO.Equals(item.MBL_NO, StringComparison.OrdinalIgnoreCase)) { p.BOOKING_ID = orderInfo.currOrder.Id; p.UpdateTime = DateTime.Now; p.UpdateBy = long.Parse(user.UserId); p.UpdateUserName = user.UserName; await tenantDb.Updateable(p).UpdateColumns(x => new { x.BOOKING_ID, x.UpdateTime, x.UpdateBy, x.UpdateUserName }).ExecuteCommandAsync(); } }); } } } catch (Exception ex) { Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 检索截单回执的订舱记录 处理异常,原因:{ex.Message}"); return DataResult.FailedData(orderInfo, $"检索失败,原因:{ex.Message}", MultiLanguageConst.Operation_Failed); } return DataResult.Success(orderInfo); } #endregion #region 处理SI截单回执 /// /// 处理SI截单回执 /// /// 截单回执任务主键 /// 返回回执 public async Task ProcessSISubmitted(long taskPkId) { bool result = false; string msg = string.Empty; TaskSiSubmitted siSubmitted = null; var tenantDb = saasService.GetBizDbScopeById(user.TenantId); try { /* 1、判断当前租户开启了自动更新订舱数据(SI_SUBMITTED_AUTO_UPDATE_ORDER=ENABLE) 2、先与订舱数据进行比对,记录比对结果。 3、更新订舱详情 4、文件挂到订舱的附件上 */ var queryList = await tenantDb.Queryable() .InnerJoin((a, b) => a.Id == b.TASK_ID) .Where((a, b) => a.Id == taskPkId) .Select((a, b) => new { Base = a, SI = b }) .ToListAsync(); var taskBaseInfo = queryList.FirstOrDefault().Base; if (queryList.Count == 0) throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPkId)); siSubmitted = queryList.FirstOrDefault().SI; //当前截单回执已有匹配的订舱订单 if (siSubmitted.BOOKING_ID.HasValue) throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskSISubmittedHasOrder))); var paramConfig = _configService.GetConfig(CONST_SI_SUBMITTED_DEFAULT_PARAM, long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value; var siCtnList = tenantDb.Queryable().Where(a => a.P_PKID == siSubmitted.Id).ToList(); var orderRlt = await _seaExportService.SearchOrderInfo(siSubmitted.MBL_NO); if (!orderRlt.Succeeded) { // 提单号 {0} 检索海运出口订单失败 throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseSearchOrderFailMBLNo)), siSubmitted.MBL_NO)); } var orderInfo = orderRlt.Data.currOrder; var codeIssueTypeList = _codeIssueTypeService.GetAllList().GetAwaiter().GetResult()?.Data; var mappingIssueTypeList = _mappingIssueTypeService.GetAllList().GetAwaiter().GetResult()?.Data; if (!string.IsNullOrWhiteSpace(paramConfig) && paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase)) { siSubmitted.IS_SET_AUTO_UPD_BOOKING = true; Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 配置了自动更新订舱详情"); if (orderInfo != null) { Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 获取了订舱详情完成 bookingid={orderInfo.Id}"); siSubmitted.BOOKING_ID = orderInfo.Id; var ctnList = orderRlt.Data.currOrderCtnList.Adapt>(); Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 获取订舱集装箱列表完成 ctnnum={ctnList.Count}"); SIFeedBackCompareDto siSrcDto = orderInfo.Adapt(); if (ctnList.Count > 0) { siSrcDto.ContaList = ctnList.Select(t => new SIFeedBackCompareContaDto { ContaNo = t.CntrNo, SealNo = t.SealNo, ContaType = t.CtnCode, ContaTypeName = t.CtnAll, PKGS = t.PKGS.HasValue ? t.PKGS.Value : 0, CBM = t.CBM, KGS = t.KGS, WeighType = t.WeightType == "累加" ? "ADD" : "ALL", WeighKGS = t.WeightKGS }).ToList(); } SIFeedBackCompareDto siTargetDto = siSubmitted.Adapt(); if (siCtnList.Count > 0) { siTargetDto.ContaList = siCtnList.Select(t => new SIFeedBackCompareContaDto { ContaNo = t.CNTRNO, SealNo = t.SEALNO, ContaType = t.CTNCODE, ContaTypeName = t.CTNALL, PKGS = t.PKGS.HasValue ? t.PKGS.Value : 0, CBM = t.CBM, KGS = t.KGS, WeighType = t.WEIGHTYPE, WeighKGS = t.WEIGHKGS }).ToList(); } Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 开始比对"); //更新前先比对一遍差异 var compareRlt = await PushCompareSIInfo(siSrcDto, siTargetDto, orderInfo.Id, taskPkId); if (string.IsNullOrWhiteSpace(compareRlt.Item1)) { siSubmitted.DIFF_NUM = compareRlt.Item2; } Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 获取比对完成 结果={JsonConvert.SerializeObject(compareRlt)}"); SeaExportOpenEditReq bkModel = null; Dictionary> changeDict = new Dictionary>(); if (orderInfo != null) { bkModel = new SeaExportOpenEditReq { Id = orderInfo.Id, //MBLNO = orderInfo.MBLNO, //ctnInputs = new List(), //ChangedFields = new List() }; if (!string.IsNullOrEmpty(siSubmitted.ISSUETYPE)) { string issueType = string.Empty; if (siSubmitted.ISSUETYPE.Equals("seaway", StringComparison.OrdinalIgnoreCase)) { //bkModel.ISSUETYPE = "seaway"; issueType = "Seaway Bill"; } else if (siSubmitted.ISSUETYPE.Equals("telex", StringComparison.OrdinalIgnoreCase)) { //bkModel.ISSUETYPE = "telex"; issueType = "Telex"; } else if (siSubmitted.ISSUETYPE.Equals("original", StringComparison.OrdinalIgnoreCase)) { //bkModel.ISSUETYPE = "original"; issueType = "Original"; } var currMap = mappingIssueTypeList.FirstOrDefault(a => a.MapName.Equals(issueType)); if (currMap != null) { var codeIssue = codeIssueTypeList.FirstOrDefault(b => b.Id == currMap.LinkId); if (codeIssue != null) { bkModel.IssueType = codeIssue.EnName; } } if (string.IsNullOrWhiteSpace(bkModel.IssueType)) { bkModel.IssueType = issueType; } changeDict.Add(nameof(bkModel.IssueType), new Tuple(true, issueType)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.ISSUETYPE)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.ISSUETYPE)); } if (!string.IsNullOrEmpty(siSubmitted.SHIPPER)) { bkModel.Shipper = siSubmitted.SHIPPER; changeDict.Add(nameof(bkModel.Shipper), new Tuple(true, siSubmitted.SHIPPER)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.SHIPPER)); } if (!string.IsNullOrEmpty(siSubmitted.CONSIGNEE)) { bkModel.Consignee = siSubmitted.CONSIGNEE; changeDict.Add(nameof(bkModel.Consignee), new Tuple(true, siSubmitted.CONSIGNEE)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.CONSIGNEE)); } if (!string.IsNullOrEmpty(siSubmitted.NOTIFYPARTY)) { bkModel.NotifyParty = siSubmitted.NOTIFYPARTY; changeDict.Add(nameof(bkModel.NotifyParty), new Tuple(true, siSubmitted.NOTIFYPARTY)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.NOTIFYPARTY)); } if (!string.IsNullOrEmpty(siSubmitted.NOTIFYPARTY2)) { bkModel.SecondNotifyParty = siSubmitted.NOTIFYPARTY2; changeDict.Add(nameof(bkModel.SecondNotifyParty), new Tuple(true, siSubmitted.NOTIFYPARTY2)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.NOTIFYPARTY2)); } if (!string.IsNullOrEmpty(siSubmitted.KINDPKGS)) { bkModel.KindPkgs = siSubmitted.KINDPKGS; changeDict.Add(nameof(bkModel.KindPkgs), new Tuple(true, siSubmitted.KINDPKGS)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.KINDPKGS)); } if (!string.IsNullOrEmpty(siSubmitted.DESCRIPTION)) { bkModel.Description = siSubmitted.DESCRIPTION; changeDict.Add(nameof(bkModel.Description), new Tuple(true, siSubmitted.DESCRIPTION)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.DESCRIPTION)); } if (!string.IsNullOrEmpty(siSubmitted.HSCODE)) { bkModel.HSCode = siSubmitted.HSCODE; changeDict.Add(nameof(bkModel.HSCode), new Tuple(true, siSubmitted.HSCODE)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.HSCODE)); } if (!string.IsNullOrEmpty(siSubmitted.MARKS)) { bkModel.Marks = siSubmitted.MARKS; changeDict.Add(nameof(bkModel.Marks), new Tuple(true, siSubmitted.MARKS)); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.MARKS)); } } if (ctnList.Count > 0) { List oddCtnList = new List(); foreach (var ctn in ctnList) { if (!string.IsNullOrWhiteSpace(ctn.CtnCode) && string.IsNullOrWhiteSpace(ctn.CntrNo) && ctn.CtnNum > 1) { for (int i = 0; i < ctn.CtnNum - 1; i++) { oddCtnList.Add(new OpCtnReq { BSNO = orderInfo.Id.ToString(), CtnCode = ctn.CtnCode, CtnAll = ctn.CtnAll, }); } ctn.CtnNum = 1; } } if (oddCtnList.Count > 0) { ctnList.AddRange(oddCtnList); } } if (siCtnList.Count > 0) { bkModel.KGS = siCtnList.Sum(x => x.KGS.HasValue ? x.KGS.Value : 0); changeDict.Add(nameof(bkModel.KGS), new Tuple(true, siSubmitted.KGS.HasValue? siSubmitted.KGS.Value.ToString():"")); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.KGS)); bkModel.PKGS = siCtnList.Sum(x => x.PKGS.HasValue ? x.PKGS.Value : 0); changeDict.Add(nameof(bkModel.PKGS), new Tuple(true, siSubmitted.PKGS.HasValue ? siSubmitted.PKGS.Value.ToString() : "")); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.PKGS)); bkModel.CBM = siCtnList.Sum(x => x.CBM.HasValue ? x.CBM.Value : 0); changeDict.Add(nameof(bkModel.CBM), new Tuple(true, siSubmitted.CBM.HasValue ? siSubmitted.CBM.Value.ToString() : "")); //bkModel.ChangedFields.Add(nameof(SaveBookingOrderInput.CBM)); siCtnList.ForEach(x => { var ctn = ctnList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(x.CNTRNO) && !string.IsNullOrWhiteSpace(a.CntrNo) && a.CntrNo.Equals(x.CNTRNO, StringComparison.OrdinalIgnoreCase)); if (ctn != null) { ctn.CtnCode = x.CTNCODE; ctn.CtnAll = x.CTNALL; ctn.CtnNum = 1; ctn.SealNo = x.SEALNO; ctn.PKGS = x.PKGS; ctn.KGS = x.KGS; ctn.WeightType = x.WEIGHTYPE; ctn.WeightKGS = x.WEIGHKGS; ctn.CBM = x.CBM; ctn.Remark += "SI Add"; //ctn.TenantId = UserManager.TENANT_ID; //ctn.CreatedTime = DateTime.Now; //ctn.CreatedUserId = UserManager.UserId; //ctn.CreatedUserName = UserManager.Name; ctn.KindPkgs = x.KINDPKGS; if (string.IsNullOrWhiteSpace(x.KINDPKGS) && !string.IsNullOrWhiteSpace(siSubmitted.KINDPKGS)) ctn.KindPkgs = siSubmitted.KINDPKGS; if (x.WEIGHKGS.HasValue && x.KGS.HasValue) ctn.TareWeight = x.WEIGHKGS.Value - x.KGS.Value; } else { ctn = ctnList.FirstOrDefault(a => a.CtnCode == x.CTNCODE && string.IsNullOrWhiteSpace(a.CntrNo)); if (ctn != null) { ctn.CntrNo = x.CNTRNO; ctn.CtnCode = x.CTNCODE; ctn.CtnAll = x.CTNALL; ctn.CtnNum = 1; ctn.SealNo = x.SEALNO; ctn.PKGS = x.PKGS; ctn.KGS = x.KGS; ctn.WeightType = x.WEIGHTYPE; ctn.WeightKGS = x.WEIGHKGS; ctn.CBM = x.CBM; ctn.Remark += "SI Add"; //ctn.TenantId = UserManager.TENANT_ID; //ctn.CreatedTime = DateTime.Now; //ctn.CreatedUserId = UserManager.UserId; //ctn.CreatedUserName = UserManager.Name; ctn.KindPkgs = x.KINDPKGS; if (string.IsNullOrWhiteSpace(x.KINDPKGS) && !string.IsNullOrWhiteSpace(siSubmitted.KINDPKGS)) ctn.KindPkgs = siSubmitted.KINDPKGS; if (x.WEIGHKGS.HasValue && x.KGS.HasValue) ctn.TareWeight = x.WEIGHKGS.Value - x.KGS.Value; } else { ctn = ctnList.FirstOrDefault(a => a.CtnAll == x.CTNALL && string.IsNullOrWhiteSpace(a.CntrNo)); if (ctn != null) { ctn.CntrNo = x.CNTRNO; ctn.CtnCode = x.CTNCODE; ctn.CtnAll = x.CTNALL; ctn.CtnNum = 1; ctn.SealNo = x.SEALNO; ctn.PKGS = x.PKGS; ctn.KGS = x.KGS; ctn.WeightType = x.WEIGHTYPE; ctn.WeightKGS = x.WEIGHKGS; ctn.CBM = x.CBM; ctn.Remark += "SI Add"; //ctn.TenantId = UserManager.TENANT_ID; //ctn.CreatedTime = DateTime.Now; //ctn.CreatedUserId = UserManager.UserId; //ctn.CreatedUserName = UserManager.Name; ctn.KindPkgs = x.KINDPKGS; if (string.IsNullOrWhiteSpace(x.KINDPKGS) && !string.IsNullOrWhiteSpace(siSubmitted.KINDPKGS)) ctn.KindPkgs = siSubmitted.KINDPKGS; if (x.WEIGHKGS.HasValue && x.KGS.HasValue) ctn.TareWeight = x.WEIGHKGS.Value - x.KGS.Value; } else { ctnList.Add(new OpCtnReq { BSNO = orderInfo.Id.ToString(), //IsDeleted = false, //cre = DateTime.Now, //UpdatedTime = DateTime.Now, //CreatedUserId = UserManager.UserId, //CreatedUserName = UserManager.Name, //TenantId = UserManager.TENANT_ID, CntrNo = x.CNTRNO, CtnCode = x.CTNCODE, CtnAll = x.CTNALL, CtnNum = 1, SealNo = x.SEALNO, PKGS = x.PKGS, KGS = x.KGS, WeightType = x.WEIGHTYPE, WeightKGS = x.WEIGHKGS, CBM = x.CBM, Remark = "SI Add", TareWeight = x.WEIGHKGS.HasValue && x.KGS.HasValue ? x.WEIGHKGS.Value - x.KGS.Value : 0, KindPkgs = (string.IsNullOrWhiteSpace(x.KINDPKGS) && !string.IsNullOrWhiteSpace(siSubmitted.KINDPKGS)) ? siSubmitted.KINDPKGS : x.KINDPKGS, }); } } } }); if (ctnList.Any(t => string.IsNullOrWhiteSpace(t.Remark) || t.Remark.IndexOf("SI Add") < 0)) { ctnList = ctnList.Where(t => !string.IsNullOrWhiteSpace(t.Remark) && t.Remark.IndexOf("SI Add") >= 0).ToList(); } } if (ctnList.Count > 0) { bkModel.CtnList = ctnList.Select(t => new OpCtnReq { BSNO = t.BSNO, CntrNo = t.CntrNo, CtnAll = t.CtnAll, CtnCode = t.CtnCode, CtnNum = t.CtnNum, CBM = t.CBM.HasValue ? t.CBM.Value : 0, KindPkgs = t.KindPkgs, PKGS = t.PKGS.HasValue ? t.PKGS.Value : 0, SealNo = t.SealNo, KGS = t.KGS.HasValue ? t.KGS.Value : 0, TareWeight = t.TareWeight.HasValue ? t.TareWeight.Value : 0, WeightKGS = t.WeightKGS.HasValue ? t.WeightKGS.Value : 0, WeightType = t.WeightType, Id = t.Id, }).ToList(); } Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 准备更新订舱数据完更"); //更新订舱数据 var bkRlt = await _seaExportCommonService.SeaExportOpenEdit(bkModel); if (bkRlt.Succeeded) { Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 更新订舱数据成功"); //推送截单货物状态 var pushModel = new EmbedServiceProjectStatusDto { businessId = bkModel.Id.ToString(), SourceType = 1, StatusCodes = new List { new EmbedServiceProjectStatusDetailDto{ StatusCode = "JD" } } }; if (siSubmitted.NOTICE_DATE.HasValue) { pushModel.StatusCodes[0].SetActDate = siSubmitted.NOTICE_DATE.Value; } var saveStatusRlt = await _djyServiceStatusService.SaveServiceStatus(pushModel); Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 推送截单状态完成 结果={JsonConvert.SerializeObject(saveStatusRlt)}"); siSubmitted.PROCESS_STATUS = "SUCC"; siSubmitted.PROCESS_DATE = DateTime.Now; siSubmitted.IS_UPDATE_BOOKING = true; siSubmitted.UPDATE_BOOKING_DATE = DateTime.Now; //直接完成SI的回执任务 if (taskBaseInfo.IS_PUBLIC == 1) { await _taskManageBaseService.SetTaskOwner(new long[] { taskBaseInfo.Id }, new List { new RecvUserInfo{ RecvUserId = orderInfo.OperatorId, RecvUserName = orderInfo.OperatorName, } }); //更新任务的状态 taskBaseInfo.IS_COMPLETE = 1; taskBaseInfo.COMPLETE_DEAL = "AUTO"; taskBaseInfo.COMPLETE_DEAL_NAME = "自动"; taskBaseInfo.COMPLETE_DATE = DateTime.Now; taskBaseInfo.UpdateTime = DateTime.Now; taskBaseInfo.UpdateBy = orderInfo.OperatorId; taskBaseInfo.UpdateUserName = orderInfo.OperatorName; await tenantDb.Updateable(taskBaseInfo).UpdateColumns(it => new { it.IS_COMPLETE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME, it.COMPLETE_DATE, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); } else { taskBaseInfo.IS_COMPLETE = 1; taskBaseInfo.COMPLETE_DEAL = "AUTO"; taskBaseInfo.COMPLETE_DEAL_NAME = "自动"; taskBaseInfo.COMPLETE_DATE = DateTime.Now; taskBaseInfo.UpdateTime = DateTime.Now; taskBaseInfo.UpdateBy = taskBaseInfo.CreateBy; taskBaseInfo.UpdateUserName = taskBaseInfo.CreateUserName; //更新任务台,将当前任务变更为个人任务 await tenantDb.Updateable(taskBaseInfo).UpdateColumns(it => new { it.IS_COMPLETE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME, it.COMPLETE_DATE, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); } /* 1、获取任务的附件 2、文件转移到订舱的附件表 */ var fileList = tenantDb.Queryable().Where(a => a.TASK_PKID == taskPkId).ToList(); //_opFileService.GetOpFileDownLoad(); ////处理附件 //var opt = App.GetOptions(); //var dirAbs = opt.basePath; //if (string.IsNullOrEmpty(dirAbs)) //{ // dirAbs = App.WebHostEnvironment.WebRootPath; //} string batchNo = SnowFlakeSingle.Instance.NextId().ToString(); //var fileList = _taskFileRepository.AsQueryable().Filter(null, true) fileList.ForEach(file => { if (file.FILE_CATEGORY == TaskFileCategoryEnum.SI_SUBMITTED.ToString()) { var currFile = _opFileService.GetOpFileDownLoad(file.Id.ToString()).Data; var fileFullPath = currFile.FilePath; if (File.Exists(fileFullPath)) { //如果确认文件读取成功 var bookFilePath = _sysFileService.MoveFile(bkModel.Id.ToString(), fileFullPath, batchNo , false, null, true).GetAwaiter().GetResult(); //将格式单附件写入订舱的附件 SaveEDIFile(bkModel.Id, fileFullPath, currFile.FileName, 0, 0).GetAwaiter(); } } }); Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 上传订舱数据附件完成"); result = true; msg = "处理成功"; Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 更新完成"); } else { siSubmitted.PROCESS_STATUS = "FAILURE"; siSubmitted.PROCESS_DATE = DateTime.Now; siSubmitted.PROCESS_RESULT = "更新订舱信息失败"; siSubmitted.UPDATE_BOOKING_DATE = DateTime.Now; result = false; msg = "处理失败"; Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 处理失败"); } } else { result = false; msg = $"提单号{siSubmitted.MBL_NO} 检索订舱数据失败"; Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 检索订舱数据失败"); } } else { result = false; msg = "当前租户没开通自动(SI回执是否自动更新订舱)"; siSubmitted.IS_SET_AUTO_UPD_BOOKING = false; //将文件同步到订舱的附件 if (orderInfo != null) { //推送截单货物状态 var pushModel = new EmbedServiceProjectStatusDto { businessId = orderInfo.Id.ToString(), SourceType = 1, StatusCodes = new List { new EmbedServiceProjectStatusDetailDto{ StatusCode = "JD" } } }; if (siSubmitted.NOTICE_DATE.HasValue) { pushModel.StatusCodes[0].SetActDate = siSubmitted.NOTICE_DATE.Value; } var saveStatusRlt = await _djyServiceStatusService.SaveServiceStatus(pushModel); Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 推送截单状态完成 结果={JsonConvert.SerializeObject(saveStatusRlt)}"); siSubmitted.PROCESS_STATUS = "SUCC"; siSubmitted.PROCESS_DATE = DateTime.Now; siSubmitted.IS_UPDATE_BOOKING = true; siSubmitted.UPDATE_BOOKING_DATE = DateTime.Now; //直接完成SI的回执任务 if (taskBaseInfo.IS_PUBLIC == 1) { await _taskManageBaseService.SetTaskOwner(new long[] { taskBaseInfo.Id }, new List { new RecvUserInfo{ RecvUserId = orderInfo.OperatorId, RecvUserName = orderInfo.OperatorName, } }); //更新任务的状态 taskBaseInfo.IS_COMPLETE = 1; taskBaseInfo.COMPLETE_DEAL = "AUTO"; taskBaseInfo.COMPLETE_DEAL_NAME = "自动"; taskBaseInfo.COMPLETE_DATE = DateTime.Now; taskBaseInfo.UpdateTime = DateTime.Now; taskBaseInfo.UpdateBy = orderInfo.OperatorId; taskBaseInfo.UpdateUserName = orderInfo.OperatorName; await tenantDb.Updateable(taskBaseInfo).UpdateColumns(it => new { it.IS_COMPLETE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME, it.COMPLETE_DATE, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); } else { taskBaseInfo.IS_COMPLETE = 1; taskBaseInfo.COMPLETE_DEAL = "AUTO"; taskBaseInfo.COMPLETE_DEAL_NAME = "自动"; taskBaseInfo.COMPLETE_DATE = DateTime.Now; taskBaseInfo.UpdateTime = DateTime.Now; taskBaseInfo.UpdateBy = taskBaseInfo.CreateBy; taskBaseInfo.UpdateUserName = taskBaseInfo.CreateUserName; //更新任务台,将当前任务变更为个人任务 await tenantDb.Updateable(taskBaseInfo).UpdateColumns(it => new { it.IS_COMPLETE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME, it.COMPLETE_DATE, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); } var fileList = tenantDb.Queryable().Where(a => a.TASK_PKID == taskPkId).ToList(); //_opFileService.GetOpFileDownLoad(); ////处理附件 //var opt = App.GetOptions(); //var dirAbs = opt.basePath; //if (string.IsNullOrEmpty(dirAbs)) //{ // dirAbs = App.WebHostEnvironment.WebRootPath; //} string batchNo = SnowFlakeSingle.Instance.NextId().ToString(); //var fileList = _taskFileRepository.AsQueryable().Filter(null, true) fileList.ForEach(file => { if (file.FILE_CATEGORY == TaskFileCategoryEnum.SI_SUBMITTED.ToString()) { var currFile = _opFileService.GetOpFileDownLoad(file.Id.ToString()).Data; var fileFullPath = currFile.FilePath; if (File.Exists(fileFullPath)) { //如果确认文件读取成功 var bookFilePath = _sysFileService.MoveFile(orderInfo.Id.ToString(), fileFullPath, batchNo , false, null, true).GetAwaiter().GetResult(); //将格式单附件写入订舱的附件 SaveEDIFile(orderInfo.Id, fileFullPath, currFile.FileName, 0, 0).GetAwaiter(); } } }); Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 上传订舱数据附件完成"); result = true; msg = "处理成功"; Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 更新完成"); } else { result = false; msg = $"提单号{siSubmitted.MBL_NO} 检索订舱数据失败"; Logger.Log(NLog.LogLevel.Info, $"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 检索订舱数据失败"); } } } catch (Exception ex) { result = false; msg = ex.Message; } if (!result) { if (siSubmitted != null) { siSubmitted.PROCESS_STATUS = "FAILURE"; siSubmitted.PROCESS_DATE = DateTime.Now; if (msg.Length > 500) { siSubmitted.PROCESS_RESULT = msg.Substring(0, 500); } else { siSubmitted.PROCESS_RESULT = msg; } await tenantDb.Updateable(siSubmitted).UpdateColumns(x => new { x.PROCESS_DATE, x.PROCESS_STATUS, x.PROCESS_RESULT, x.DIFF_NUM, x.IS_SET_AUTO_UPD_BOOKING, }).ExecuteCommandAsync(); //new EmailNoticeHelper().SendEmailNotice($"MBLNO={siSubmitted.MBL_NO} SI回执回写失败", $"MBLNO={siSubmitted.MBL_NO} SI回执回写失败,原因:{result.msg}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList()); } return DataResult.Failed(msg); } else { await tenantDb.Updateable(siSubmitted).UpdateColumns(x => new { x.PROCESS_DATE, x.PROCESS_STATUS, x.PROCESS_RESULT, x.IS_UPDATE_BOOKING, x.UPDATE_BOOKING_DATE, x.DIFF_NUM, x.BOOKING_ID, x.IS_SET_AUTO_UPD_BOOKING }).ExecuteCommandAsync(); return DataResult.Successed(msg); } } #endregion #region 推送BC变更比对 /// /// 推送BC变更比对sysUser /// /// 订舱详情 /// SI截单详情 /// 订舱主键 /// 任务ID /// [NonAction] public async Task> PushCompareSIInfo(SIFeedBackCompareDto siSrcDto, SIFeedBackCompareDto siTargetDto, long bookingId, long taskPKId) { string result = string.Empty; int diffNum = 0; var tenantDb = saasService.GetBizDbScopeById(user.TenantId); string batchNo = SnowFlakeSingle.Instance.NextId().ToString(); DateTime bDate = DateTime.Now; var compareResult = await ExcuteCompare(siSrcDto, siTargetDto); DateTime eDate = DateTime.Now; TimeSpan ts = eDate.Subtract(bDate); var timeDiff = ts.TotalMilliseconds; if (compareResult != null) { Logger.Log(NLog.LogLevel.Info, "批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, compareResult.succ ? "成功" : "失败"); if (!compareResult.succ) { result = $"比对失败,原因:{compareResult.msg}"; } } if (compareResult != null) { DateTime nowDate = DateTime.Now; var hisInfo = tenantDb.Queryable().First(a => a.BUSI_ID == bookingId.ToString() && a.TASK_ID == taskPKId); if (hisInfo == null) { BusinessCompareDiffRecord entity = new BusinessCompareDiffRecord { BUSI_ID = bookingId.ToString(), TASK_ID = taskPKId, BUSI_TYPE = "SI_SUBMITTED", COMPARE_DIFF_NUM = compareResult.extra.IsExistsDiff ? compareResult.extra.ShowDetailList.Count : 0, CreateTime = nowDate, UpdateTime = nowDate, CreateBy = long.Parse(user.UserId), CreateUserName = user.UserName, UpdateBy = long.Parse(user.UserId), UpdateUserName = user.UserName, COMPARE_TYPE = "SI_MODIFY", COMPARE_RLT = JsonConvert.SerializeObject(compareResult.extra.ShowDetailList), }; await tenantDb.Insertable(entity).ExecuteCommandAsync(); } else { hisInfo.COMPARE_DIFF_NUM = compareResult.extra.IsExistsDiff ? compareResult.extra.ShowDetailList.Count : 0; hisInfo.UpdateTime = nowDate; hisInfo.UpdateBy = long.Parse(user.UserId); hisInfo.UpdateUserName = user.UserName; hisInfo.COMPARE_RLT = JsonConvert.SerializeObject(compareResult.extra.ShowDetailList); await tenantDb.Updateable(hisInfo).UpdateColumns(it => new { it.COMPARE_DIFF_NUM, it.COMPARE_RLT, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); } if (compareResult.extra.ShowDetailList == null || compareResult.extra.ShowDetailList.Count == 0) { result = $"比对失败,没有比对出差异"; //new EmailNoticeHelper().SendEmailNotice($"MBLNO={siSrcDto.MblNo} SI 回执比对差异失败,比对结果为0", $"MBLNO={siSrcDto.MblNo} SI 回执比对差异失败,比对结果为0", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList()); } else { diffNum = compareResult.extra.ShowDetailList.Count; } } else { result = $"比对失败,未获取到比对结果"; //new EmailNoticeHelper().SendEmailNotice($"MBLNO={siSrcDto.MblNo} SI 回执比对差异失败,未获取到比对结果", $"MBLNO={siSrcDto.MblNo} SI 回执比对差异失败,未获取到比对结果", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList()); } return new Tuple(result, diffNum); } #endregion #region 请求BC比对 /// /// 请求SI比对 /// /// 订舱详情 /// SI截单详情 /// 返回回执 [NonAction] public async Task ExcuteCompare(SIFeedBackCompareDto siSrcDto, SIFeedBackCompareDto siTargetDto) { TaskManageExcuteResultDto model = null; /* 1、读取配置文件中的规则引擎URL 2、填充请求的类,并生成JSON报文 3、POST请求接口,并记录回执。 4、返回信息。 */ var url = "";//App.Configuration["SICompareUrl"]; using (var httpClient = new HttpClient()) { try { using (var reduceAttach = new MultipartFormDataContent()) { var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(siSrcDto))); dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue($"form-data") { Name = "srcJson" }; reduceAttach.Add(dataContent); var dataContent2 = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(siTargetDto))); dataContent2.Headers.ContentDisposition = new ContentDispositionHeaderValue($"form-data") { Name = "destJson" }; reduceAttach.Add(dataContent2); //请求 var response = httpClient.PostAsync(url, reduceAttach).Result; var result = response.Content.ReadAsStringAsync().Result; model = JsonConvert.DeserializeObject(result); } } catch (Exception ex) { Logger.Log(NLog.LogLevel.Info, "推送SI比对异常,原因:{error}", ex.Message); //throw Oops.Oh($"推送SI比对异常,原因:{ex.Message}"); } } return model; } #endregion #region 获取订舱详情 /// /// 获取订舱详情 /// /// 任务主键 /// 返回结果 public async Task> GetBookingOrderInfo(long taskPKId) { TaskBookingOrderDto model = null; var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var taskInfo = tenantDb.Queryable().First(t => t.Id == taskPKId); if (taskInfo == null) throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId)); var orderInfo = _seaExportService.SearchOrderInfo(taskInfo.MBL_NO).GetAwaiter().GetResult().Data; if (orderInfo != null) { //订舱 model = orderInfo.Adapt(); var contaList = orderInfo.currOrderCtnList; //获取集装箱的主键 var ctnArg = contaList.Select(t => t.Id).ToArray(); //查询集装箱所有的货物信息 var cargoList = new List(); //Logger.Log(NLog.LogLevel.Info, "批次={no} 提取货物明细完成 数量={total}", batchNo, cargoList.Count); if (cargoList.Count > 0) { model.ContaList = contaList.GroupJoin(cargoList, l => l.Id, r => r.CtnId, (l, r) => { var currList = r.ToList(); if (currList.Count > 0) { var info = l.Adapt(); info.CargoList = currList.Adapt>(); return info; } return l.Adapt(); }).ToList(); } else { model.ContaList = contaList.Adapt>(); } //任务 model.TaskBaseInfo = taskInfo.Adapt(); } return DataResult.Success(model); } #endregion #region 获取SI反馈信息 /// /// 获取SI反馈信息 /// /// 任务主键 /// 返回结果 public async Task> GetSIFeedBackInfo(long taskPKId) { TaskSIFeedBackResultDto model = new TaskSIFeedBackResultDto(); var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var siFeedBackList = tenantDb.Queryable() .InnerJoin((si, ctn) => si.Id == ctn.P_PKID) .Where((si, ctn) => si.TASK_ID == taskPKId) .Select((si, ctn) => new { si = si, ctn = ctn }).ToList(); if (siFeedBackList.Count == 0) throw new Exception($"SI反馈信息不存在"); var mblNo = siFeedBackList.FirstOrDefault().si.MBL_NO; var orderInfoData = _seaExportService.SearchOrderInfo(mblNo).GetAwaiter().GetResult().Data; var orderInfo = orderInfoData.currOrder; model.TaskId = taskPKId; var siFeedBackInfo = siFeedBackList.FirstOrDefault().si; var resultInfo = siFeedBackInfo.Adapt(); resultInfo.ContaList = siFeedBackList.Select(t => t.ctn.Adapt()).ToList(); model.BusiInfo = resultInfo; if (orderInfo != null) { //订舱 model.BookingOrder = orderInfo.Adapt(); } //进行数据比对确认差异字段KEY var mainDiff = await InnerCompareMainInfoDiff(orderInfo, siFeedBackInfo); model.SICompareOrderKeyList = mainDiff; var contaDiff = await InnerCompareContaInfoDiff(orderInfoData.currOrderCtnList, siFeedBackList.Select(t => t.ctn).ToList()); model.SICompareOrderContaKeyList = contaDiff; return DataResult.Success(model); } #endregion #region 比较主信息 /// /// 比较主信息 /// /// 订舱详情 /// SI反馈详情 /// 返回差异 private async Task> InnerCompareMainInfoDiff(SeaExportRes bookingOrder, TaskSiSubmitted taskSIFeedBackInfo) { List resultList = new List(); //需要比对的字段 var compareField = new string[] { "SHIPPER", "CONSIGNEE", "NOTIFYPARTY", "MARKS", "DESCRIPTION", "BLFRT", "SERVICE", "ISSUETYPE", "PORTLOAD", "PORTDISCHARGE", "TRANSPORT", "DESTINATION", "PKGS", "KGS", "CBM", "KINDPKGS", "THIRDPAYADDR" }; var bookProps = typeof(SeaExportRes).GetProperties(); var feedProps = typeof(TaskSiSubmitted).GetProperties(); resultList = bookProps.GroupJoin(feedProps, l => l.Name.ToUpper(), r => r.Name.ToUpper(), (l, r) => { if (compareField.Any(x => x.Equals(l.Name, StringComparison.OrdinalIgnoreCase))) { var currList = r.ToList(); if (currList.Count > 0) { var si = r.FirstOrDefault(); var bkVal = l.GetValue(bookingOrder); var siVal = si.GetValue(taskSIFeedBackInfo); if (l.PropertyType == typeof(string)) { string st1 = string.Empty; string st2 = string.Empty; if (bkVal == null) { st1 = ""; } else { st1 = (bkVal as string).AdjustString(); } if (siVal == null) { st2 = ""; } else { st2 = (siVal as string).AdjustString(); } if (!st1.Equals(st2)) { return l.Name.ToUpper(); } return string.Empty; } else if (l.PropertyType == typeof(int?)) { var dt1 = bkVal as int?; var dt2 = siVal as int?; if (!dt1.Equals(dt2)) { return l.Name.ToUpper(); } return string.Empty; } else if (l.PropertyType == typeof(decimal?)) { var dt1 = bkVal as decimal?; var dt2 = siVal as decimal?; if (!dt1.Equals(dt2)) { return l.Name.ToUpper(); } return string.Empty; } } return string.Empty; } return string.Empty; }).Where(t => !string.IsNullOrWhiteSpace(t)).ToList(); return resultList; } #endregion #region 比较箱信息 /// /// 比较箱信息 /// /// 订舱箱信息 /// SI反馈箱信息 /// 返回差异 private async Task> InnerCompareContaInfoDiff(List bookContaList, List siContaList) { List resultList = new List(); var bookProps = typeof(OpCtnRes).GetProperties(); var feedProps = typeof(TaskSiSubmittedCtn).GetProperties(); resultList = siContaList.GroupJoin(bookContaList, l => l.CNTRNO, r => r.CntrNo, (l, r) => { var currList = r.ToList(); if (currList.Count > 0) { var bkCtn = currList.FirstOrDefault(); if (!l.KGS.Equals(bkCtn.KGS) || !l.PKGS.Equals(bkCtn.PKGS) || !l.SEALNO.Equals(bkCtn.SealNo) || !l.CTNALL.Equals(bkCtn.CtnAll) || !l.CBM.Equals(bkCtn.CBM)) { return l.CNTRNO; } return String.Empty; } return l.CNTRNO; }).Where(t => !string.IsNullOrWhiteSpace(t)).ToList(); return resultList; } #endregion #region 异步写入附件表 /// /// 异步写入附件表 /// /// 订舱ID /// 文件路径 /// 文件名 /// 租户ID /// 附件类型代码 /// 附件类型名称 /// 附件模块代码 /// [NonAction] private async Task> SaveEDIFile(long boookId, string FilePath, string fileName, long tenantId, int fileSize, string fileTypeCode = "sifeed", string fileTypeName = "SI submitted", string moudle = "TaskSISubmitted") { /* 直接将附件信息写入附件表 */ //EDI文件 var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var bookFile = new OpFile { FileName = fileName, FilePath = FilePath, TypeCode = fileTypeCode, TypeName = fileTypeName, LinkId = boookId, FileSize = fileSize, FileType = Path.GetExtension(fileName), Extension = Path.GetExtension(fileName), OrgId = user.OrgId }; await tenantDb.Insertable(bookFile).ExecuteCommandAsync(); return DataResult.Success(string.Empty); } #endregion } #region 整理文本数据 public static class CompareObjExtension { /// /// 整理文本数据 /// /// 文本 /// public static string AdjustString(this string str) { if (string.IsNullOrWhiteSpace(str)) return str; var rtn = str.Replace("\r\n", "\n").Trim(); if (rtn.EndsWith("\n")) { rtn = rtn.Substring(0, rtn.Length - 1); } return rtn; } /// /// 文本转换成日期 /// /// 文本 /// 字段名称 /// 返回日期 public static Nullable GetDateTime(this string str, string MemberName) { if (string.IsNullOrWhiteSpace(str)) return null; DateTime currDate = DateTime.MinValue; if (!DateTime.TryParse(str, out currDate)) throw new Exception(string.Format("字段{0}={1}转换日期失败,请检查日期格式", MemberName, str)); return currDate; } } #endregion }