You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BookingHeChuan/Myshipping.Application/Service/TaskManagePlat/TaskCautionNoticeService.cs

844 lines
44 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
{
/// <summary>
/// 重要提醒任务
/// </summary>
[ApiDescriptionSettings("Application", Name = "TaskCautionNotice", Order = 10)]
public class TaskCautionNoticeService : ITaskCautionNoticeService, IDynamicApiController, ITransient
{
private readonly ISysCacheService _cache;
private readonly ILogger<TaskCautionNoticeService> _logger;
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
private readonly SqlSugarRepository<TaskCautionNoticeInfo> _taskCautionNoticeInfoRepository;
private readonly SqlSugarRepository<TaskCautionNoticeDetailInfo> _taskCautionNoticeDetailInfoRepository;
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccount;
private readonly SqlSugarRepository<TaskCautionNoticeWholeShipInfo> _taskCautionNoticeWholeShipInfoRepository;
private readonly SqlSugarRepository<TaskCautionNoticeWholeShipDetailInfo> _taskCautionNoticeWholeShipDetailInfoRepository;
private readonly SqlSugarRepository<BookingSlotBase> _repBase;
private readonly SqlSugarRepository<BookingSlotCtn> _repCtn;
private readonly SqlSugarRepository<BookingSlotAllocation> _repAllocation;
private readonly SqlSugarRepository<BookingSlotAllocationCtn> _repAllocationCtn;
private readonly SqlSugarRepository<BookingOrder> _repBookingOrder;
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
public TaskCautionNoticeService(ISysCacheService cache, ILogger<TaskCautionNoticeService> logger,
SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
SqlSugarRepository<TaskCautionNoticeInfo> taskCautionNoticeInfoRepository,
SqlSugarRepository<TaskCautionNoticeDetailInfo> taskCautionNoticeDetailInfoRepository,
SqlSugarRepository<TaskCautionNoticeWholeShipInfo> taskCautionNoticeWholeShipInfoRepository,
SqlSugarRepository<TaskCautionNoticeWholeShipDetailInfo> taskCautionNoticeWholeShipDetailInfoRepository,
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount,
SqlSugarRepository<BookingSlotBase> repBase,
SqlSugarRepository<BookingSlotCtn> repCtn, SqlSugarRepository<BookingSlotAllocation> repAllocation,
SqlSugarRepository<BookingSlotAllocationCtn> repAllocationCtn,
SqlSugarRepository<BookingOrder> repBookingOrder,
SqlSugarRepository<SysUser> 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 获取重要提醒任务详情
/// <summary>
/// 获取重要提醒任务详情
/// </summary>
/// <param name="taskPkId">重要提醒任务主键</param>
/// <returns>返回详情</returns>
[HttpGet("/TaskCautionNotice/GetInfoByTaskId")]
public async Task<TaskCautionNoticeShowDto> 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 触发推送消息
/// <summary>
/// 触发推送消息
/// </summary>
/// <param name="taskPKId">重要提醒任务主键</param>
/// <param name="tenantId">租户ID</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskCautionNotice/TriggerSendNotice")]
public async Task<TaskManageOrderResultDto> 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<AttachesInfo>()
};
_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 推送邮件
/// <summary>
/// 推送邮件
/// </summary>
/// <param name="emailApiUserDefinedDto">自定义邮件详情</param>
/// <param name="filePath">文件路径</param>
/// <returns>返回回执</returns>
private async Task<CommonWebApiResult> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto)
{
CommonWebApiResult result = new CommonWebApiResult { succ = true };
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
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 生成重要提醒整船通知
/// <summary>
/// 生成重要提醒整船通知
/// </summary>
/// <param name="model">请求详情</param>
/// <returns>返回回执</returns>
public async Task<TaskManageOrderResultDto> 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).Where(a =>
a.VESSEL_OLD_VAL == model.VesselOldVal && a.VOYNO_OLD_VAL == model.VoynoOldVal && a.STAT_DAY.Value == statDay)
.WhereIF(!string.IsNullOrWhiteSpace(model.VesselNewVal),x=> x.VESSEL_NEW_VAL == model.VesselNewVal)
.WhereIF(!string.IsNullOrWhiteSpace(model.VoynoNewVal), x => x.VOYNO_NEW_VAL == model.VoynoNewVal)
.WhereIF(!string.IsNullOrWhiteSpace(model.SICutOldVal), x => x.SI_CUT_OLD_VAL == model.SICutOldVal)
.WhereIF(!string.IsNullOrWhiteSpace(model.SICutNewVal), x => x.SI_CUT_NEW_VAL == model.SICutNewVal)
.WhereIF(!string.IsNullOrWhiteSpace(model.VGMCutOldVal), x => x.VGM_CUT_OLD_VAL == model.VGMCutOldVal)
.WhereIF(!string.IsNullOrWhiteSpace(model.VGMCutNewVal), x => x.VGM_CUT_NEW_VAL == model.VGMCutNewVal)
.WhereIF(!string.IsNullOrWhiteSpace(model.DirectToTransOldVal), x => x.DIRECT_TO_TRANS_OLD_VAL == model.DirectToTransOldVal)
.WhereIF(!string.IsNullOrWhiteSpace(model.DirectToTransNewVal), x => x.DIRECT_TO_TRANS_NEW_VAL == model.DirectToTransNewVal).FirstAsync();
var detailRecordList = new List<TaskCautionNoticeWholeShipDetailInfo>();
if (shipInfo == null)
{
shipInfo = 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 = model.IsCutDateAdvanced,
IS_VESSEL_CHANGE = model.IsVesselChange,
IS_TRANSFER = model.IsTransfer,
CreatedTime = nowDate,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name,
TenantId = UserManager.TENANT_ID,
TenantName = UserManager.TENANT_NAME,
STAT_DAY = statDay,
};
await _taskCautionNoticeWholeShipInfoRepository.InsertAsync(shipInfo);
//检索所有订舱记录
var bookingSlotAllocList = _repBase.AsQueryable().Filter(null, true)
.LeftJoin<BookingSlotAllocation>((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<BookingOrder> bookingOrderList = new List<BookingOrder>();
//先批量取一遍关联的订舱记录
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<long> userIds = new List<long>();
List<SysUser> userList = new List<SysUser>();
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 = shipInfo.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 = shipInfo.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 = 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);
}
});
}
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<BookingSlotAllocation>((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<long> userIds = new List<long>();
List<SysUser> userList = new List<SysUser>();
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);
}
}
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<TaskCautionNoticeWholeShipDetailInfo> 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 (!string.IsNullOrWhiteSpace(shipInfo.VGM_CUT_OLD_VAL) && !string.IsNullOrWhiteSpace(shipInfo.VGM_CUT_NEW_VAL))
{
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_NEW_VAL);
contentBuilder.AppendLine("=================");
}
}
if (!string.IsNullOrWhiteSpace(shipInfo.SI_CUT_OLD_VAL) && !string.IsNullOrWhiteSpace(shipInfo.SI_CUT_NEW_VAL))
{
if (!shipInfo.SI_CUT_OLD_VAL.Equals(shipInfo.SI_CUT_NEW_VAL, StringComparison.OrdinalIgnoreCase))
{
contentBuilder.AppendLine("SI截止时间提前");
contentBuilder.AppendLine("原:" + shipInfo.SI_CUT_OLD_VAL);
contentBuilder.AppendLine("新:" + shipInfo.SI_CUT_NEW_VAL);
contentBuilder.AppendLine("=================");
}
}
}
//船名航次变更
if (shipInfo.IS_VESSEL_CHANGE)
{
contentBuilder.AppendLine("船名航次变更");
contentBuilder.AppendLine("原:" + $"{shipInfo.VESSEL_OLD_VAL}/{shipInfo.VOYNO_OLD_VAL}");
contentBuilder.AppendLine("新:" + $"{shipInfo.VESSEL_NEW_VAL}/{shipInfo.VOYNO_NEW_VAL}");
contentBuilder.AppendLine("=================");
}
//直达变中转
if (shipInfo.IS_TRANSFER)
{
contentBuilder.AppendLine("直达变中转");
contentBuilder.AppendLine("原:" + shipInfo.DIRECT_TO_TRANS_OLD_VAL);
contentBuilder.AppendLine("新:" + shipInfo.DIRECT_TO_TRANS_NEW_VAL);
contentBuilder.AppendLine("=================");
}
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(15, ' ')}|未分配操作");
}
else
{
contentBuilder.AppendLine($"{p.Key.PadRight(15, ' ')}|{(string.Join(",", p.userList.Select(x => x.NOTIFY_USER_NAME).Distinct().ToArray()).PadRight(40, ' '))}");
}
});
var mobileArg = detailList.Select(p => p.NOTIFY_MOBILE).Distinct().ToArray();
_logger.LogInformation($"准备钉钉通知,内容:\r\n{contentBuilder.ToString()}");
DingTalkGroupHelper.SendDingTalkGroupMessage($"{tenantId}_Notify", "重要通知提醒", $"{contentBuilder.ToString()}", false, mobileArg, null);
_logger.LogInformation($"钉钉通知完成");
detailList.ForEach(async t =>
{
await _taskCautionNoticeWholeShipDetailInfoRepository.AsUpdateable(t).UpdateColumns(p => new
{
p.STATUS,
p.STATUS_NAME,
}).ExecuteCommandAsync();
});
}
catch(Exception ex)
{
_logger.LogInformation($"重要通知提醒主键shipInfo={shipInfo.PK_ID} 推送钉钉通知异常 原因:{ex.Message}");
new EmailNoticeHelper().SendEmailNotice($"重要通知提醒主键shipInfo={shipInfo.PK_ID} 推送钉钉通知异常", $"重要通知提醒主键shipInfo={shipInfo.PK_ID} 推送钉钉通知异常 原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
}
}
}
}