|
|
using Furion;
|
|
|
using Furion.EventBus;
|
|
|
using Furion.FriendlyException;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using Mapster;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Myshipping.Application.ConfigOption;
|
|
|
using Myshipping.Application.Entity;
|
|
|
using Myshipping.Application.Service.BookingOrder.Dto;
|
|
|
using Myshipping.Core;
|
|
|
using Myshipping.Core.Entity;
|
|
|
using Myshipping.Core.Service;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
namespace Myshipping.Application.Event
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 订舱同步给客户订舱系统
|
|
|
/// </summary>
|
|
|
public class BookingSyncSubscriber : IEventSubscriber
|
|
|
{
|
|
|
private IServiceProvider _services { get; }
|
|
|
private readonly ILogger<BookingSyncSubscriber> _logger;
|
|
|
|
|
|
public BookingSyncSubscriber(IServiceProvider services, ILogger<BookingSyncSubscriber> logger)
|
|
|
{
|
|
|
_services = services;
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
//发送订舱同步数据给客户订舱系统
|
|
|
[EventSubscribe("SendToCustomer:Book")]
|
|
|
public async Task SendToCustomer(EventHandlerExecutingContext context)
|
|
|
{
|
|
|
_logger.LogInformation($"收到订舱同步客户订舱系统请求:{context.Source.Payload}");
|
|
|
var bookId = (long)context.Source.Payload;
|
|
|
using var scope = _services.CreateScope();
|
|
|
var repoCutomerOrder = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingCustomerOrder>>();
|
|
|
var repoOrder = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingOrder>>();
|
|
|
var repoCtn = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingCtn>>();
|
|
|
var repoFile = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingFile>>();
|
|
|
|
|
|
var repoStaLog = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingStatusLog>>();
|
|
|
var repoStaLogDetail = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingStatusLogDetail>>();
|
|
|
var repoGoodsSta = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingGoodsStatus>>();
|
|
|
var repoGoodsStaCfg = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingGoodsStatusConfig>>();
|
|
|
|
|
|
var cacheService = scope.ServiceProvider.GetRequiredService<ISysCacheService>();
|
|
|
|
|
|
var custOrder = await repoCutomerOrder.AsQueryable().Filter(null, true).FirstAsync(x => x.BookingId == bookId);
|
|
|
if (custOrder == null) //非客户订舱系统过来的数据
|
|
|
{
|
|
|
_logger.LogInformation($"ID为 {bookId} 的数据并非来自客户订舱系统,不继续处理数据回推");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var order = await repoOrder.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == bookId);
|
|
|
var ctns = await repoCtn.AsQueryable().Filter(null, true).Where(x => x.BILLID == bookId).ToListAsync();
|
|
|
var files = await repoFile.AsQueryable().Filter(null, true).Where(x => x.BookingId == bookId).ToListAsync();
|
|
|
var staLogs = await repoStaLog.AsQueryable().Filter(null, true).Where(x => x.BookingId == bookId).ToListAsync();
|
|
|
var staLogDetails = await repoStaLogDetail.AsQueryable().Filter(null, true).Where(x => staLogs.Select(y => y.Id).Contains(x.PId)).ToListAsync();
|
|
|
var goodsLogs = await repoGoodsSta.AsQueryable().Filter(null, true).Where(x => x.bookingId == bookId).ToListAsync();
|
|
|
var goodsLogConfigs = await repoGoodsStaCfg.AsQueryable().Filter(null, true).Where(x => goodsLogs.Select(y => y.ConfigId).Contains(x.Id)).ToListAsync();
|
|
|
|
|
|
//把ID还原为客户订舱系统中的ID
|
|
|
order.Id = Convert.ToInt64(order.BSNO);
|
|
|
order.BSNO = null;
|
|
|
ctns.ForEach(x => x.BILLID = order.Id);
|
|
|
files.ForEach(x => x.BookingId = order.Id);
|
|
|
staLogs.ForEach(x => x.BookingId = order.Id);
|
|
|
goodsLogs.ForEach(x => x.bookingId = order.Id);
|
|
|
|
|
|
|
|
|
var staLogSendList = staLogs.Adapt<List<BookingStatusLogSyncCustomerDto>>();
|
|
|
staLogSendList.ForEach(x =>
|
|
|
{
|
|
|
x.Details = staLogDetails.Where(y => y.PId == x.Id).Adapt<List<BookingStatusLogDetailSyncCustomerDto>>();
|
|
|
});
|
|
|
|
|
|
//发送对象
|
|
|
var sendObj = new BookingCustomerRecDataFeedbackDto()
|
|
|
{
|
|
|
Order = order.Adapt<BookingOrderSyncCustomerDto>(),
|
|
|
Ctns = ctns.Adapt<List<BookingCtnSyncCustomerDto>>(),
|
|
|
Files = files.Adapt<List<BookingFileSyncCustomerDto>>(),
|
|
|
StatusLogs = staLogSendList
|
|
|
};
|
|
|
|
|
|
|
|
|
//文件内容
|
|
|
var opt = App.GetOptions<BookingAttachOptions>();
|
|
|
var dirAbs = opt.basePath;
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
{
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
}
|
|
|
|
|
|
foreach (var file in files)
|
|
|
{
|
|
|
var fileFullPath = Path.Combine(dirAbs, file.FilePath);
|
|
|
if (File.Exists(fileFullPath))
|
|
|
{
|
|
|
sendObj.Files.First(x => x.Id == file.Id).FileContent = File.ReadAllBytes(fileFullPath);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//回推回执
|
|
|
var recFeedbackConfig = cacheService.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackURL");
|
|
|
if (recFeedbackConfig == null || string.IsNullOrEmpty(recFeedbackConfig.Value))
|
|
|
{
|
|
|
throw Oops.Bah("回推订舱数据的URL地址未配置,请联系管理员");
|
|
|
}
|
|
|
|
|
|
var recFeedbackUserKey = cacheService.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackUserKey");
|
|
|
if (recFeedbackUserKey == null || string.IsNullOrEmpty(recFeedbackUserKey.Value))
|
|
|
{
|
|
|
throw Oops.Bah("回推订舱数据的用户KEY未配置,请联系管理员");
|
|
|
}
|
|
|
|
|
|
var recFeedbackUserSecret = cacheService.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackUserSecret");
|
|
|
if (recFeedbackUserSecret == null || string.IsNullOrEmpty(recFeedbackUserSecret.Value))
|
|
|
{
|
|
|
throw Oops.Bah("回推订舱数据的用户秘钥未配置,请联系管理员");
|
|
|
}
|
|
|
|
|
|
var feedbackUrl = recFeedbackConfig.Value;
|
|
|
if (!feedbackUrl.EndsWith("/"))
|
|
|
{
|
|
|
feedbackUrl += "/";
|
|
|
}
|
|
|
|
|
|
feedbackUrl += "DataSync/RecBookingDataFeedback";
|
|
|
|
|
|
_logger.LogInformation($"准备发送客户订舱数据同步:{sendObj.ToJsonString()},URL:{feedbackUrl}");
|
|
|
|
|
|
var rtn = await feedbackUrl
|
|
|
.SetHeaders(new Dictionary<string, object> {
|
|
|
{ CommonConst.API_USER_HEADER_KEY, recFeedbackUserKey.Value},
|
|
|
{ CommonConst.API_USER_HEADER_SECRET, recFeedbackUserSecret.Value}
|
|
|
})
|
|
|
.SetBody(sendObj)
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
_logger.LogInformation($"回推数据同步返回:{rtn}");
|
|
|
|
|
|
var jobjRtn = JObject.Parse(rtn);
|
|
|
if (jobjRtn.GetIntValue("code") != 200)
|
|
|
{
|
|
|
throw Oops.Bah(jobjRtn.GetStringValue("message"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//推送货物状态到客户订舱系统
|
|
|
[EventSubscribe("SyncGoodStatus:Book")]
|
|
|
public async Task SyncGoodStatus(EventHandlerExecutingContext context)
|
|
|
{
|
|
|
_logger.LogInformation($"收到推送货物状态到客户订舱系统:{context.Source.Payload}");
|
|
|
GoodsStatusSyncDto payload = context.Source.Payload as GoodsStatusSyncDto;
|
|
|
|
|
|
using var scope = _services.CreateScope();
|
|
|
var repoCutomerOrder = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingCustomerOrder>>();
|
|
|
var repoOrder = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingOrder>>();
|
|
|
|
|
|
var cacheService = scope.ServiceProvider.GetRequiredService<ISysCacheService>();
|
|
|
|
|
|
var custOrder = await repoCutomerOrder.AsQueryable().Filter(null, true).FirstAsync(x => x.BookingId == payload.Id);
|
|
|
if (custOrder == null) //非客户订舱系统过来的数据
|
|
|
{
|
|
|
_logger.LogInformation($"ID为 {payload.Id} 的数据并非来自客户订舱系统,不继续处理数据回推");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var order = await repoOrder.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == payload.Id);
|
|
|
|
|
|
//把ID还原为客户订舱系统中的ID
|
|
|
payload.Id = Convert.ToInt64(order.BSNO);
|
|
|
|
|
|
|
|
|
//回推回执
|
|
|
var recFeedbackConfig = cacheService.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackURL");
|
|
|
if (recFeedbackConfig == null || string.IsNullOrEmpty(recFeedbackConfig.Value))
|
|
|
{
|
|
|
throw Oops.Bah("回推订舱数据的URL地址未配置,请联系管理员");
|
|
|
}
|
|
|
|
|
|
var recFeedbackUserKey = cacheService.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackUserKey");
|
|
|
if (recFeedbackUserKey == null || string.IsNullOrEmpty(recFeedbackUserKey.Value))
|
|
|
{
|
|
|
throw Oops.Bah("回推订舱数据的用户KEY未配置,请联系管理员");
|
|
|
}
|
|
|
|
|
|
var recFeedbackUserSecret = cacheService.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackUserSecret");
|
|
|
if (recFeedbackUserSecret == null || string.IsNullOrEmpty(recFeedbackUserSecret.Value))
|
|
|
{
|
|
|
throw Oops.Bah("回推订舱数据的用户秘钥未配置,请联系管理员");
|
|
|
}
|
|
|
|
|
|
var feedbackUrl = recFeedbackConfig.Value;
|
|
|
if (!feedbackUrl.EndsWith("/"))
|
|
|
{
|
|
|
feedbackUrl += "/";
|
|
|
}
|
|
|
|
|
|
feedbackUrl += "DataSync/RecGoodsStatusSync";
|
|
|
|
|
|
_logger.LogInformation($"准备发送货物状态数据同步:{payload.ToJsonString()},URL:{feedbackUrl}");
|
|
|
|
|
|
var rtn = await feedbackUrl
|
|
|
.SetHeaders(new Dictionary<string, object> {
|
|
|
{ CommonConst.API_USER_HEADER_KEY, recFeedbackUserKey.Value},
|
|
|
{ CommonConst.API_USER_HEADER_SECRET, recFeedbackUserSecret.Value}
|
|
|
})
|
|
|
.SetBody(payload)
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
_logger.LogInformation($"回推数据同步返回:{rtn}");
|
|
|
|
|
|
var jobjRtn = JObject.Parse(rtn);
|
|
|
if (jobjRtn.GetIntValue("code") != 200)
|
|
|
{
|
|
|
throw Oops.Bah(jobjRtn.GetStringValue("message"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//推送货物状态通知
|
|
|
[EventSubscribe("GoodsStatusSubscribeNotify:Book")]
|
|
|
public async Task GoodsStatusSubscribeNotify(EventHandlerExecutingContext context)
|
|
|
{
|
|
|
_logger.LogInformation($"收到推送货物状态通知请求:{context.Source.Payload}");
|
|
|
|
|
|
dynamic payload = context.Source.Payload;
|
|
|
long bookId = payload.BookingId;
|
|
|
string statusCode = payload.StatusCode;
|
|
|
string statusName = payload.StatusName;
|
|
|
|
|
|
using var scope = _services.CreateScope();
|
|
|
var cache = scope.ServiceProvider.GetRequiredService<ISysCacheService>();
|
|
|
var repoOrder = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingOrder>>();
|
|
|
var repoBookingGoodsStatusSubscribe = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingGoodsStatusSubscribe>>();
|
|
|
|
|
|
var order = await repoOrder.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == bookId);
|
|
|
|
|
|
var subList = await repoBookingGoodsStatusSubscribe.AsQueryable().Filter(null, true).Where(x => x.IsDeleted == false && x.BookingId == bookId).ToListAsync();
|
|
|
foreach (var sub in subList)
|
|
|
{
|
|
|
if (sub.SendMail && !string.IsNullOrEmpty(sub.Email) && sub.StatusCode.Split(',').Contains(statusCode))
|
|
|
{
|
|
|
var subject = $"大简云-货物通知:{order.MBLNO}---{order.VESSEL}/{order.VOYNO}{statusName}";
|
|
|
var body = $"尊敬的客户,您好:<br/><br/>您所订阅的提单号{order.MBLNO} ,船名航次{order.VESSEL}/{order.VOYNO}的业务{statusName}。<br/><br/>—— 此邮件为大简云平台自动发送,请勿回复。<br/><br/><img src='https://wechat.myshipping.net:8860/wechat_image/banner.png' style='width:300px;'/>";
|
|
|
|
|
|
var sendUrlCfg = cache.GetAllDictData().Result.FirstOrDefault(x => x.Code == "email_api_url");
|
|
|
if (sendUrlCfg == null)
|
|
|
{
|
|
|
_logger.LogError($"未配置邮件发送URL,推送货物状态通知邮件未能发送。订舱ID:{bookId},状态:{statusName}({statusCode}),邮箱:{sub.Email}");
|
|
|
}
|
|
|
|
|
|
var mailJson = new dynamic[]{
|
|
|
new
|
|
|
{
|
|
|
SendTo = sub.Email,
|
|
|
Title = subject,
|
|
|
Body = body,
|
|
|
SmtpConfig = "SERVICE"
|
|
|
}
|
|
|
};
|
|
|
var mailStr = mailJson.ToJsonString();
|
|
|
|
|
|
_logger.LogInformation($"准备推送货物状态邮件通知,JSON:{mailStr},订舱ID:{bookId},状态:{statusName}({statusCode}),邮箱:{sub.Email}");
|
|
|
|
|
|
var rtn = await sendUrlCfg.Value
|
|
|
.SetBody(mailStr)
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
_logger.LogError($"推送货物状态通知邮件发送返回:{rtn}。订舱ID:{bookId},状态:{statusName}({statusCode}),邮箱:{sub.Email}");
|
|
|
|
|
|
var jsonRtn = JObject.Parse(rtn);
|
|
|
if (jsonRtn.GetBooleanValue("Success"))
|
|
|
{
|
|
|
_logger.LogInformation($"推送货物状态通知邮件发送成功。订舱ID:{bookId},状态:{statusName}({statusCode}),邮箱:{sub.Email}");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_logger.LogError($"推送货物状态通知邮件发送失败:{jsonRtn.GetStringValue("Message")}。订舱ID:{bookId},状态:{statusName}({statusCode}),邮箱:{sub.Email}。");
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|