using Furion.DependencyInjection; using Furion.DynamicApiController; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Myshipping.Application.Entity; using Myshipping.Application.Service.TaskManagePlat.Interface; using Myshipping.Core.Service; using Myshipping.Core; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Furion.FriendlyException; using Myshipping.Core.Entity; using Furion.JsonSerialization; using Furion.RemoteRequest.Extensions; using Newtonsoft.Json; using System.IO; using System.Net.Http; using Myshipping.Core.Helper; using NPOI.SS.Formula.Functions; using System.Reflection.Metadata; using Furion; using Myshipping.Application.Helper; using Furion.DistributedIDGenerator; namespace Myshipping.Application { /// /// 重要提醒任务 /// [ApiDescriptionSettings("Application", Name = "TaskCautionNotice", Order = 10)] public class TaskCautionNoticeService : ITaskCautionNoticeService, IDynamicApiController, ITransient { private readonly ISysCacheService _cache; private readonly ILogger _logger; private readonly SqlSugarRepository _taskBaseRepository; private readonly SqlSugarRepository _taskCautionNoticeInfoRepository; private readonly SqlSugarRepository _taskCautionNoticeDetailInfoRepository; private readonly SqlSugarRepository _djyUserMailAccount; private readonly SqlSugarRepository _taskCautionNoticeWholeShipInfoRepository; private readonly SqlSugarRepository _taskCautionNoticeWholeShipDetailInfoRepository; private readonly SqlSugarRepository _repBase; private readonly SqlSugarRepository _repCtn; private readonly SqlSugarRepository _repAllocation; private readonly SqlSugarRepository _repAllocationCtn; private readonly SqlSugarRepository _repBookingOrder; private readonly SqlSugarRepository _sysUserRepository; public TaskCautionNoticeService(ISysCacheService cache, ILogger logger, SqlSugarRepository taskBaseRepository, SqlSugarRepository taskCautionNoticeInfoRepository, SqlSugarRepository taskCautionNoticeDetailInfoRepository, SqlSugarRepository taskCautionNoticeWholeShipInfoRepository, SqlSugarRepository taskCautionNoticeWholeShipDetailInfoRepository, SqlSugarRepository djyUserMailAccount, SqlSugarRepository repBase, SqlSugarRepository repCtn, SqlSugarRepository repAllocation, SqlSugarRepository repAllocationCtn, SqlSugarRepository repBookingOrder, SqlSugarRepository sysUserRepository) { _cache = cache; _logger = logger; _taskBaseRepository = taskBaseRepository; _taskCautionNoticeInfoRepository = taskCautionNoticeInfoRepository; _taskCautionNoticeDetailInfoRepository = taskCautionNoticeDetailInfoRepository; _djyUserMailAccount = djyUserMailAccount; _taskCautionNoticeWholeShipInfoRepository = taskCautionNoticeWholeShipInfoRepository; _taskCautionNoticeWholeShipDetailInfoRepository = taskCautionNoticeWholeShipDetailInfoRepository; _repBase = repBase; _repCtn = repCtn; _repAllocation = repAllocation; _repAllocationCtn = repAllocationCtn; _repBookingOrder = repBookingOrder; _sysUserRepository = sysUserRepository; } #region 获取重要提醒任务详情 /// /// 获取重要提醒任务详情 /// /// 重要提醒任务主键 /// 返回详情 [HttpGet("/TaskCautionNotice/GetInfoByTaskId")] public async Task GetInfoByTaskId(string taskPkId) { TaskCautionNoticeShowDto dto = new TaskCautionNoticeShowDto(); var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId); if (taskBase == null) throw Oops.Oh($"任务主键{taskPkId}无法获取业务信息"); var noticeInfo = _taskCautionNoticeInfoRepository.AsQueryable().First(a => a.TASK_ID == taskBase.PK_ID); if (noticeInfo == null) throw Oops.Oh($"重要提醒主键{taskPkId}无法获取业务信息"); CautionNoticeTaskEnum cautionNoticeEnum = (CautionNoticeTaskEnum)System.Enum.Parse(typeof(CautionNoticeTaskEnum), noticeInfo.CAUTION_NOTICE_TYPE); dto = new TaskCautionNoticeShowDto { PKId = noticeInfo.PK_ID, taskPKId = noticeInfo.TASK_ID, carrier = noticeInfo.CARRIER, bookingId = noticeInfo.BOOKING_ID, mblNo = noticeInfo.MBL_NO, createTime = noticeInfo.CreatedTime, cautionNoticeType = noticeInfo.CAUTION_NOTICE_TYPE, cautionNoticeTypeName = cautionNoticeEnum.GetDescription(), origVal = noticeInfo.OLD_VAL, newVal = noticeInfo.NEW_VAL }; return dto; } #endregion #region 触发推送消息 /// /// 触发推送消息 /// /// 重要提醒任务主键 /// 租户ID /// 返回回执 [HttpGet("/TaskCautionNotice/TriggerSendNotice")] public async Task TriggerSendNotice(string taskPKId, long tenantId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { TaskDraftShowDto dto = new TaskDraftShowDto(); var taskBase = _taskBaseRepository.AsQueryable().Filter(null, true).First(a => a.PK_ID == taskPKId && a.IsDeleted == false && a.TenantId == tenantId); if (taskBase == null) throw Oops.Oh($"任务主键{taskPKId}无法获取业务信息"); var noticeInfo = _taskCautionNoticeInfoRepository.AsQueryable().Filter(null, true).First(a => a.TASK_ID == taskBase.PK_ID && a.IsDeleted == false && a.TenantId == tenantId); var list = _taskCautionNoticeDetailInfoRepository.AsQueryable().Filter(null, true) .Where(a => a.P_ID == noticeInfo.PK_ID && a.IsDeleted == false && a.TenantId == tenantId).ToList(); TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), taskBase.TASK_TYPE); CautionNoticeTaskEnum cautionNoticeEnum = (CautionNoticeTaskEnum)System.Enum.Parse(typeof(CautionNoticeTaskEnum), noticeInfo.CAUTION_NOTICE_TYPE); if (list.Count > 0) { list.ForEach(a => { if (a.NOTIFY_METHOD == CautionNoticeMethodEnum.Email.ToString()) { if (!string.IsNullOrWhiteSpace(a.NOTIFY_EMAIL)) { //提取当前公共邮箱的配置 DjyUserMailAccount publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.TenantId == tenantId && x.ShowName == "PublicSend" && x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != ""); if (publicMailAccount == null) { //throw Oops.Oh($"提取公共邮箱配置失败,请在用户邮箱账号管理增加配置显示名为PublicSend或者配置个人邮箱"); _logger.LogInformation($"准备邮件通知通知给 uid={a.NOTIFY_USER_NAME} name={a.NOTIFY_USER_NAME},但是没有配置发送邮箱"); new EmailNoticeHelper().SendEmailNotice($"MBLNO={noticeInfo.MBL_NO} {cautionNoticeEnum.GetDescription()} 需要给推送邮件但是没有配公司邮箱", $"MBLNO={noticeInfo.MBL_NO} {cautionNoticeEnum.GetDescription()} 需要给推送邮件但是没有配公司邮箱", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList()); } EmailApiUserDefinedDto emailApiUserDefinedDto = new EmailApiUserDefinedDto { SendTo = a.NOTIFY_EMAIL, Title = $"提单号:{noticeInfo.MBL_NO} {cautionNoticeEnum.GetDescription()}", Body = $"提单号:{noticeInfo.MBL_NO} {cautionNoticeEnum.GetDescription()} {noticeInfo.NOTIFY_CONTENT}", Account = publicMailAccount.MailAccount?.Trim(), Password = publicMailAccount.Password?.Trim(), Server = publicMailAccount.SmtpServer?.Trim(), Port = publicMailAccount.SmtpPort.HasValue ? publicMailAccount.SmtpPort.Value : 465, UseSSL = publicMailAccount.SmtpSSL.HasValue ? publicMailAccount.SmtpSSL.Value : true, Attaches = new List() }; _logger.LogInformation($"生成请求邮件参数,结果:{JSON.Serialize(emailApiUserDefinedDto)}"); //推送邮件 var emailRlt = PushEmail(emailApiUserDefinedDto).GetAwaiter().GetResult(); _logger.LogInformation($"推送邮件完成,结果:{JSON.Serialize(emailRlt)}"); a.STATUS = emailRlt.succ ? "SUCC" : "FAILURE"; a.STATUS_NAME = emailRlt.succ ? "成功" : "失败"; _taskCautionNoticeDetailInfoRepository.AsUpdateable(a).UpdateColumns(p => new { p.STATUS, p.STATUS_NAME }).ExecuteCommand(); } } else if (a.NOTIFY_METHOD == CautionNoticeMethodEnum.DingDing.ToString()) { _logger.LogInformation($"准备钉钉通知给 uid={a.NOTIFY_USER_NAME} name={a.NOTIFY_USER_NAME},内容:\r\n{noticeInfo.NOTIFY_CONTENT}"); DingTalkGroupHelper.SendDingTalkGroupMessage($"{taskBase.TenantId}_Notify", cautionNoticeEnum.GetDescription(), $"{noticeInfo.NOTIFY_CONTENT}\r\n{a.NOTIFY_USER_NAME}", false, new string[] { a.NOTIFY_MOBILE }, null); _logger.LogInformation($"钉钉通知完毕给 uid={a.NOTIFY_USER_NAME} name={a.NOTIFY_USER_NAME},内容:\r\n{noticeInfo.NOTIFY_CONTENT}"); a.STATUS = "SUCC"; a.STATUS_NAME = "成功"; _taskCautionNoticeDetailInfoRepository.AsUpdateable(a).UpdateColumns(p => new { p.STATUS, p.STATUS_NAME }).ExecuteCommand(); } }); } } catch (Exception ex) { new EmailNoticeHelper().SendEmailNotice($"taskPKId={taskPKId} 有重要提醒任务发生异常", $"taskPKId={taskPKId} 有重要提醒任务发生异常 原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList()); } return result; } #endregion #region 推送邮件 /// /// 推送邮件 /// /// 自定义邮件详情 /// 文件路径 /// 返回回执 private async Task PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto) { CommonWebApiResult result = new CommonWebApiResult { succ = true }; List emailList = new List(); var emailUrl = _cache.GetAllDictData().GetAwaiter().GetResult() .FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "email_api_url")?.Value; if (emailUrl == null) throw Oops.Bah("字典未配置 url_set->email_api_url 请联系管理员"); emailList.Add(emailApiUserDefinedDto); //string strJoin = System.IO.File.ReadAllText(filePath); DateTime bDate = DateTime.Now; HttpResponseMessage res = null; try { res = await emailUrl.SetBody(emailList, "application/json").PostAsync(); } catch (Exception ex) { _logger.LogInformation($"发送邮件异常:{ex.Message}"); } DateTime eDate = DateTime.Now; TimeSpan ts = eDate.Subtract(bDate); var timeDiff = ts.TotalMilliseconds; _logger.LogInformation($"邮件上传完成 用时:{timeDiff}ms.,"); _logger.LogInformation($"发送邮件返回:{JSON.Serialize(res)}"); if (res != null && res.StatusCode == System.Net.HttpStatusCode.OK) { var userResult = await res.Content.ReadAsStringAsync(); var respObj = JsonConvert.DeserializeAnonymousType(userResult, new { Success = false, Message = string.Empty, Code = -9999, }); result.succ = respObj.Success; result.msg = respObj.Message; } return result; } #endregion #region 生成重要提醒整船通知 /// /// 生成重要提醒整船通知 /// /// 请求详情 /// 返回回执 public async Task GenerateWholeShipCaucation(CautionNoticeTaskWholeShipDto model, BookingSlotBase slotBaseInfo) { TaskManageOrderResultDto rlt = new TaskManageOrderResultDto(); try { /* 1、优先匹配是否已经有了整船的通知(船名、航次、SI截止时间、VGM截止时间、直达变中转、统计日期必须是当日的,注新值和旧值提交的都一致) 2、如果能匹配到,并且明细里有此单号,不做处理;没有单号记录需要写入单号,并且重新发起当票的邮件和钉钉通知 3、如果没有匹配到,重新获取整船的单号,生成明细记录。发起邮件和钉钉通知 */ DateTime nowDate = DateTime.Now; string batchNo = IDGen.NextID().ToString(); int statDay = int.Parse(nowDate.ToString("yyyyMMdd")); var shipInfo = await _taskCautionNoticeWholeShipInfoRepository.AsQueryable().Filter(null, true).FirstAsync(a => a.VESSEL_OLD_VAL == model.VesselOldVal && a.VESSEL_NEW_VAL == model.VesselNewVal && a.VOYNO_OLD_VAL == model.VoynoOldVal && a.VOYNO_NEW_VAL == model.VoynoNewVal && a.SI_CUT_OLD_VAL == model.SICutOldVal && a.SI_CUT_NEW_VAL == model.SICutNewVal && a.VGM_CUT_OLD_VAL == model.VGMCutOldVal && a.VGM_CUT_NEW_VAL == model.VGMCutNewVal && a.DIRECT_TO_TRANS_OLD_VAL == model.DirectToTransOldVal && a.DIRECT_TO_TRANS_NEW_VAL == model.DirectToTransNewVal && a.STAT_DAY != null && a.STAT_DAY.Value == statDay); var detailRecordList = new List(); if (shipInfo == null) { TaskCautionNoticeWholeShipInfo shipEntity = new TaskCautionNoticeWholeShipInfo { PK_ID = IDGen.NextID().ToString(), CARRIER = model.Carrier, IsDeleted = false, VESSEL_OLD_VAL = model.VesselOldVal, VESSEL_NEW_VAL = model.VesselNewVal, VOYNO_OLD_VAL = model.VoynoOldVal, VOYNO_NEW_VAL = model.VoynoNewVal, VGM_CUT_OLD_VAL = model.VGMCutOldVal, VGM_CUT_NEW_VAL = model.VGMCutNewVal, SI_CUT_OLD_VAL = model.SICutOldVal, SI_CUT_NEW_VAL = model.SICutNewVal, DIRECT_TO_TRANS_OLD_VAL = model.DirectToTransOldVal, DIRECT_TO_TRANS_NEW_VAL = model.DirectToTransNewVal, IS_CUT_DATE_ADVANCED = !string.IsNullOrWhiteSpace(model.SICutNewVal), IS_VESSEL_CHANGE = !string.IsNullOrWhiteSpace(model.VesselNewVal), IS_TRANSFER = !string.IsNullOrWhiteSpace(model.DirectToTransNewVal), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, STAT_DAY = statDay, }; await _taskCautionNoticeWholeShipInfoRepository.InsertAsync(shipEntity); //检索所有订舱记录 var bookingSlotAllocList = _repBase.AsQueryable().Filter(null, true) .LeftJoin((slot, alloc) => slot.Id == alloc.BOOKING_SLOT_ID) .Where((slot, alloc) => slot.VESSEL == model.VesselOldVal && slot.VOYNO == model.VoynoOldVal && slot.CARRIERID == model.Carrier && slot.IsDeleted == false && slot.TenantId == UserManager.TENANT_ID && (alloc == null || alloc.IsDeleted == false)) .Select((slot, alloc) => new { Slot = slot, Alloc = alloc }).ToList(); List bookingOrderList = new List(); //先批量取一遍关联的订舱记录 if (bookingSlotAllocList.Any(t => t.Alloc != null)) { var bookingNoList = bookingSlotAllocList.Where(a => a.Alloc != null) .Select(a => a.Alloc.BOOKING_ID).ToList(); bookingOrderList = _repBookingOrder.AsQueryable().Filter(null, true) .Where(x => bookingNoList.Contains(x.Id) && x.IsDeleted == false && x.TenantId == UserManager.TENANT_ID).ToList(); } //生成完记录 bookingSlotAllocList.ForEach(t => { //舱位分配表不为空表示有对应的订舱记录 if (t.Alloc != null) { var bookingOrder = bookingOrderList.FirstOrDefault(b => b.Id == t.Alloc.BOOKING_ID); List userIds = new List(); List userList = new List(); if (!string.IsNullOrWhiteSpace(bookingOrder.OPID)) userIds.Add(long.Parse(bookingOrder.OPID)); if (!string.IsNullOrWhiteSpace(bookingOrder.CUSTSERVICEID)) userIds.Add(long.Parse(bookingOrder.CUSTSERVICEID)); userIds.Add(bookingOrder.CreatedUserId.Value); userIds = userIds.Distinct().ToList(); userList = _sysUserRepository.AsQueryable().Filter(null, true) .Where(x => userIds.Contains(x.Id) && x.IsDeleted == false && x.TenantId == UserManager.TENANT_ID).ToList(); userList.ForEach(user => { //表示即有舱位也有订舱记录 var detailInfo = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipEntity.PK_ID, BOOKING_ID = t.Alloc.BOOKING_ID, BOOKING_SLOT_ID = t.Slot.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = bookingOrder.MBLNO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.Email.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detailInfo); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detailInfo); //表示即有舱位也有订舱记录 var detail2Info = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipEntity.PK_ID, BOOKING_ID = t.Alloc.BOOKING_ID, BOOKING_SLOT_ID = t.Slot.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = bookingOrder.MBLNO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.DingDing.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detail2Info); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detail2Info); }); } else { //表示只有舱位 //表示即有舱位也有订舱记录 var createUserId = t.Slot.CreatedUserId.Value; var user = _sysUserRepository.AsQueryable().Filter(null, true) .First(x => x.Id == createUserId && x.IsDeleted == false && x.TenantId == UserManager.TENANT_ID); var detailInfo = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipEntity.PK_ID, BOOKING_SLOT_ID = t.Slot.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = t.Slot.SLOT_BOOKING_NO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.Email.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detailInfo); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detailInfo); //表示即有舱位也有订舱记录 var detail2Info = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipEntity.PK_ID, BOOKING_SLOT_ID = t.Slot.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = t.Slot.SLOT_BOOKING_NO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.DingDing.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detail2Info); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detail2Info); } }); } else { var detailList = _taskCautionNoticeWholeShipDetailInfoRepository.AsQueryable().Filter(null, true) .Where(a => a.P_ID == shipInfo.PK_ID).ToList(); var bookingSlotAllocList = _repBase.AsQueryable().Filter(null, true) .LeftJoin((slot, alloc) => slot.Id == alloc.BOOKING_SLOT_ID) .Where((slot, alloc) => slot.SLOT_BOOKING_NO == model.MBLNo && slot.CARRIERID == model.Carrier && slot.IsDeleted == false && slot.TenantId == UserManager.TENANT_ID && (alloc == null || alloc.IsDeleted == false)) .Select((slot, alloc) => new { Slot = slot, Alloc = alloc }).ToList(); if (bookingSlotAllocList.Any(t => t.Alloc != null)) { var bookingNoList = bookingSlotAllocList.Where(a => a.Alloc != null) .Select(a => a.Alloc.BOOKING_ID).ToList(); var lostList = bookingNoList.GroupJoin(detailList.Where(p => p.BOOKING_ID > 0).ToList(), l => l, r => r.BOOKING_ID, (l, r) => { var currList = r.ToList(); if (currList.Count == 0) return new { Succ = false, obj = l }; return new { Succ = true, obj = l }; }).Where(p => p.Succ == false).ToList(); if (lostList.Count > 0) { var bookingOrderList = _repBookingOrder.AsQueryable().Filter(null, true) .Where(x => bookingNoList.Contains(x.Id) && x.IsDeleted == false && x.TenantId == UserManager.TENANT_ID).ToList(); _logger.LogInformation($"提单号:{model.MBLNo} 检索通知消息没有发送过,需要补发通知"); foreach (var md in lostList) { var bookingOrder = bookingOrderList.FirstOrDefault(p => p.Id == md.obj); List userIds = new List(); List userList = new List(); if (!string.IsNullOrWhiteSpace(bookingOrder.OPID)) userIds.Add(long.Parse(bookingOrder.OPID)); if (!string.IsNullOrWhiteSpace(bookingOrder.CUSTSERVICEID)) userIds.Add(long.Parse(bookingOrder.CUSTSERVICEID)); userIds.Add(bookingOrder.CreatedUserId.Value); userIds = userIds.Distinct().ToList(); userList = _sysUserRepository.AsQueryable().Filter(null, true) .Where(x => userIds.Contains(x.Id) && x.IsDeleted == false && x.TenantId == UserManager.TENANT_ID).ToList(); var slotInfo = bookingSlotAllocList .FirstOrDefault(x => x.Alloc != null && x.Alloc.BOOKING_ID == bookingOrder.Id).Slot; userList.ForEach(user => { //表示即有舱位也有订舱记录 var detailInfo = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipInfo.PK_ID, BOOKING_ID = bookingOrder.Id, BOOKING_SLOT_ID = slotInfo.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = bookingOrder.MBLNO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.Email.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detailInfo); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detailInfo); //表示即有舱位也有订舱记录 var detail2Info = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipInfo.PK_ID, BOOKING_ID = bookingOrder.Id, BOOKING_SLOT_ID = slotInfo.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = bookingOrder.MBLNO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.DingDing.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detail2Info); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detail2Info); }); } } } else { bookingSlotAllocList.ForEach(t => { var slotInfo = detailList.FirstOrDefault(p => p.BOOKING_SLOT_ID == t.Slot.Id); if (slotInfo == null) { //表示只有舱位 //表示即有舱位也有订舱记录 var createUserId = t.Slot.CreatedUserId.Value; var user = _sysUserRepository.AsQueryable().Filter(null, true) .First(x => x.Id == createUserId && x.IsDeleted == false && x.TenantId == UserManager.TENANT_ID); var detailInfo = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipInfo.PK_ID, BOOKING_SLOT_ID = t.Slot.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = t.Slot.SLOT_BOOKING_NO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.Email.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detailInfo); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detailInfo); //表示即有舱位也有订舱记录 var detail2Info = new TaskCautionNoticeWholeShipDetailInfo { PK_ID = IDGen.NextID().ToString(), P_ID = shipInfo.PK_ID, BOOKING_SLOT_ID = t.Slot.Id, BATCH_NO = batchNo, IsDeleted = false, MBL_NO = t.Slot.SLOT_BOOKING_NO, STATUS = "TEMP", STATUS_NAME = "暂存", NOTIFY_METHOD = CautionNoticeMethodEnum.DingDing.ToString(), NOTIFY_USER_ID = user.Id.ToString(), NOTIFY_USER_NAME = user.Name, NOTIFY_MOBILE = user.Phone?.Trim(), NOTIFY_EMAIL = user.Email?.Trim(), CreatedTime = nowDate, CreatedUserId = UserManager.UserId, CreatedUserName = UserManager.Name, TenantId = UserManager.TENANT_ID, TenantName = UserManager.TENANT_NAME, }; detailRecordList.Add(detail2Info); _taskCautionNoticeWholeShipDetailInfoRepository.InsertAsync(detail2Info); } }); } } if(detailRecordList.Count > 0) { //推送邮件 await PushDingdingNotice(detailRecordList, shipInfo, slotBaseInfo); //推送钉钉 await PushEmailNotice(detailRecordList); } } catch (Exception ex) { new EmailNoticeHelper().SendEmailNotice($"slotid={model.SlotId} 推送重要提醒整船通知异常", $"slotid={model.SlotId} 推送重要提醒整船通知异常 原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList()); } return rlt; } #endregion private async Task PushDingdingNotice(List detailList, TaskCautionNoticeWholeShipInfo shipInfo, BookingSlotBase slotInfo) { try { var tenantId = detailList.FirstOrDefault().TenantId; StringBuilder contentBuilder = new StringBuilder(); contentBuilder.AppendLine("起运港:"+ slotInfo.PLACERECEIPT); contentBuilder.AppendLine("目的港:" + slotInfo.PLACEDELIVERY); contentBuilder.AppendLine("船名/航次:" + $"{slotInfo.VESSEL}/{slotInfo.VOYNO}"); contentBuilder.AppendLine("ETD:" + (slotInfo.ETD.HasValue ? slotInfo.ETD.Value.ToString("yyyy-MM-dd") : "")); contentBuilder.AppendLine("================="); //截止时间提前 if (shipInfo.IS_CUT_DATE_ADVANCED) { if (shipInfo.VGM_CUT_OLD_VAL.Equals(shipInfo.VGM_CUT_NEW_VAL, StringComparison.OrdinalIgnoreCase)) { contentBuilder.AppendLine("VGM截止时间提前"); contentBuilder.AppendLine("原:"+ shipInfo.VGM_CUT_OLD_VAL); contentBuilder.AppendLine("新:" + shipInfo.VGM_CUT_OLD_VAL); } if (shipInfo.SI_CUT_OLD_VAL.Equals(shipInfo.SI_CUT_NEW_VAL, StringComparison.OrdinalIgnoreCase)) { contentBuilder.AppendLine("SI截止时间提前"); contentBuilder.AppendLine("原:" + shipInfo.VGM_CUT_OLD_VAL); contentBuilder.AppendLine("新:" + shipInfo.VGM_CUT_OLD_VAL); } } //船名航次变更 if (shipInfo.IS_VESSEL_CHANGE) { if (shipInfo.VESSEL_OLD_VAL.Equals(shipInfo.VESSEL_NEW_VAL, StringComparison.OrdinalIgnoreCase) || shipInfo.VOYNO_OLD_VAL.Equals(shipInfo.VOYNO_NEW_VAL, StringComparison.OrdinalIgnoreCase)) { contentBuilder.AppendLine("船名航次变更"); contentBuilder.AppendLine("原:" + $"{shipInfo.VESSEL_OLD_VAL}/{shipInfo.VOYNO_OLD_VAL}"); contentBuilder.AppendLine("新:" + $"{shipInfo.VESSEL_NEW_VAL}/{shipInfo.VOYNO_NEW_VAL}"); } } //直达变中转 if (shipInfo.IS_TRANSFER) { contentBuilder.AppendLine("直达变中转"); contentBuilder.AppendLine("原:" + shipInfo.DIRECT_TO_TRANS_OLD_VAL); contentBuilder.AppendLine("新:" + shipInfo.DIRECT_TO_TRANS_NEW_VAL); } contentBuilder.AppendLine("提单号 |对应操作 "); detailList.GroupBy(a => a.MBL_NO).Select(p => { return new { Key = p.Key, userList = p.ToList() }; }).ToList().ForEach(p => { if (!p.userList.FirstOrDefault().BOOKING_ID.HasValue) { contentBuilder.AppendLine($"{p.Key.PadRight(20, ' ')}|未分配操作"); } else { contentBuilder.AppendLine($"{p.Key.PadRight(20, ' ')}|{(string.Join(",", p.userList.Select(x => x.NOTIFY_USER_NAME).ToArray()).PadRight(40, ' '))}"); } }); var mobileArg = detailList.Select(p => p.NOTIFY_MOBILE).Distinct().ToArray(); //_logger.LogInformation($"准备钉钉通知给 uid={a.NOTIFY_USER_NAME} name={a.NOTIFY_USER_NAME},内容:\r\n{noticeInfo.NOTIFY_CONTENT}"); DingTalkGroupHelper.SendDingTalkGroupMessage($"{tenantId}_Notify", "重要通知提醒", $"{contentBuilder.ToString()}", false, mobileArg, null); //_logger.LogInformation($"钉钉通知完毕给 uid={a.NOTIFY_USER_NAME} name={a.NOTIFY_USER_NAME},内容:\r\n{noticeInfo.NOTIFY_CONTENT}"); //a.STATUS = "SUCC"; //a.STATUS_NAME = "成功"; //_taskCautionNoticeDetailInfoRepository.AsUpdateable(a).UpdateColumns(p => new //{ // p.STATUS, // p.STATUS_NAME //}).ExecuteCommand(); } catch(Exception ex) { } } public async Task PushEmailNotice(List detailList) { try { } catch (Exception ex) { } } } }