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.

210 lines
9.5 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 DS.Module.PrintModule;
using DS.WMS.Core.Code.Entity;
using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using DS.WMS.Core.Op.Interface;
using DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor;
using DS.WMS.Core.Sys.Entity;
using HtmlAgilityPack;
using Newtonsoft.Json;
using RazorEngineCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Mapster;
using DS.Module.Core;
using Masuit.Tools;
using Masuit.Tools.Systems;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor.Booking;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
/// <summary>
/// 业务邮件发送服务
/// </summary>
public class MailService : ServiceBase
{
ITaskMailService service;
ISeaExportService seService;
IConfiguration config;
ApiFox Api = DefaultActionExecutor.Api;
/// <summary>
/// 初始化
/// </summary>
/// <param name="provider"></param>
public MailService(IServiceProvider provider) : base(provider)
{
service = provider.GetRequiredService<ITaskMailService>();
seService = provider.GetRequiredService<ISeaExportService>();
config = provider.GetRequiredService<IConfiguration>();
}
/// <summary>
/// 发送业务邮件
/// </summary>
/// <param name="mailConfig">邮件配置</param>
/// <param name="businessId">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <returns></returns>
public async Task<DataResult> SendAsync(BusinessTaskMail mailConfig,
long businessId, BusinessType businessType = BusinessType.OceanShippingExport)
{
ArgumentNullException.ThrowIfNull(mailConfig, nameof(mailConfig));
var result = seService.GetSeaExportInfo(businessId.ToString());
if (!result.Succeeded || result.Data == null)
return DataResult.Failed($"未能获取Id={businessId}的{businessType.GetDescription()}数据");
string title, content = string.Empty;
var templateModel = new MailTemplateModel<SeaExportOrder> { Primary = result.Data.Adapt<SeaExportOrder>() };
IRazorEngine razorEngine = new RazorEngine();
try
{
var titleTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportOrder>>>(mailConfig.Title);
title = await titleTemplate.RunAsync(x =>
{
x.Model = templateModel;
});
var contentTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportOrder>>>(mailConfig.Content);
content = await contentTemplate.RunAsync(x =>
{
x.Model = templateModel;
});
}
catch (Exception ex)
{
await ex.LogAsync(Db);
return DataResult.Failed($"渲染邮件模板({mailConfig.Id})时出错,请检查模板是否有语法错误");
}
//设置发件人
long senderId = 0;
if (mailConfig.Sender.IsSale)
senderId = templateModel.Primary.SaleId;
else if (mailConfig.Sender.IsOperator)
senderId = templateModel.Primary.OperatorId;
else if (mailConfig.Sender.IsCustomerService)
senderId = templateModel.Primary.CustomerService;
else if (mailConfig.Sender.IsVouchingClerk)
senderId = templateModel.Primary.Doc;
var sender = await Db.Queryable<SysUser>().Where(x => x.Id == senderId).Select(x => new { x.UserName, x.SignatureHtml }).FirstAsync();
if (sender == null)
return DataResult.Failed("未设置发件人");
var senderConfig = await TenantDb.Queryable<CodeUserEmail>().FirstAsync(x => x.CreateBy == senderId);
if (senderConfig == null)
return DataResult.Failed($"发件人用户:{sender.UserName} 未设置SMTP发件信息");
//插入发件人签名
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(content);
var node = htmlDoc.GetElementbyId("sign");
if (node != null)
node.InnerHtml = sender.SignatureHtml;
StringWriter writer = new();
htmlDoc.Save(writer);
content = writer.ToString();
writer.Close();
//设置收件人
List<long> receiverIds = [];
if (mailConfig.Receiver.IsCarrier)
receiverIds.Add(templateModel.Primary.CarrierId);
if (mailConfig.Receiver.IsBooking)
receiverIds.Add(templateModel.Primary.ForwarderId);
if (mailConfig.Receiver.IsYard)
receiverIds.Add(templateModel.Primary.YardId);
if (mailConfig.Receiver.IsTruck)
receiverIds.Add(templateModel.Primary.TruckerId);
if (mailConfig.Receiver.IsController)
receiverIds.Add(templateModel.Primary.CustomerId);
var receiverList = await TenantDb.Queryable<InfoClient>().Where(x => receiverIds.Contains(x.Id) && x.Email != null && x.Email != string.Empty)
.Select(x => new { x.ShortName, x.EnShortName, x.Email }).ToListAsync();
var attachmentList = mailConfig.Attachments == null ? [] : new List<Tuple<string, string>>(mailConfig.Attachments.Count);
try
{
//需要上传附件
if (mailConfig.Attachments?.Count > 0)
{
if (Api.DefaultHeaders.Contains("Authorization"))
Api.DefaultHeaders.Remove("Authorization");
Api.DefaultHeaders.Add("Authorization", "Bearer " + User.GetToken());
long tenantId = long.Parse(User.TenantId);
string requestUrl = config["TaskMail:FileBaseUrl"] + config["TaskMail:SQLPrint"];
foreach (var item in mailConfig.Attachments)
{
var req = new OpenPrintReq
{
ParamJsonStr = JsonConvert.SerializeObject(new { Id = businessId }),
PrintType = ((int)FileFormat.PDF).ToString(),
TemplateId = item.TemplateId,
TenantId = tenantId
};
var reqResult = await Api.PostAsync<PrintResult>(requestUrl, req);
if (!reqResult.Succeeded)
return DataResult.Failed($"未能获取打印API生成的文件请求地址{requestUrl}");
string url = config["TaskMail:FileBaseUrl"] + @"/PrintTempFile/" + reqResult.Data.Data;
var fileResult = await Api.SendRequestAsync(HttpMethod.Get, url);
if (!fileResult.Succeeded)
return DataResult.Failed($"未能获取打印API生成的文件附件地址{url}");
string fileName = item.FileName.IsNullOrEmpty() ? Path.GetFileName(reqResult.Data.Data) : item.FileName;
var bytes = await fileResult.Data.Content.ReadAsByteArrayAsync();
string base64Str = Convert.ToBase64String(bytes);
attachmentList.Add(new Tuple<string, string>(fileName, base64Str));
}
}
dynamic[] mailParams = [new
{
SendTo = string.Join(",", receiverList.Select(x => x.Email)),
Title = title,
Body = content,
ShowName = senderConfig.ShowName.IsNullOrEmpty() ? sender.UserName : senderConfig.ShowName,
Account = senderConfig.MailAccount,
senderConfig.Password,
Server = senderConfig.SmtpServer,
Port = senderConfig.SmtpPort.GetValueOrDefault(),
UseSSL = senderConfig.SmtpSSL.GetValueOrDefault(),
Attaches = attachmentList.Select(x => new
{
AttachName = x.Item1,
AttachContent = x.Item2
}).ToList()
}];
var mailResult = await Api.SendRequestAsync(HttpMethod.Post, config["TaskMail:MailApiUrl"], mailParams);
if (mailResult.Data.IsSuccessStatusCode)
{
return DataResult.Successed($"已发邮件(委托单:{templateModel.Primary.CustomerNo}),收件人:"
+ string.Join(",", receiverList.Select(x => x.Email)) + "发件人:" + senderConfig.MailAccount);
}
return DataResult.Failed($"邮件发送失败API返回状态为{(int)mailResult.Data.StatusCode} {mailResult.Data.StatusCode}"
+"(委托单:{templateModel.Primary.CustomerNo}),收件人:"
+ string.Join(",", receiverList.Select(x => x.Email))
+ "发件人:" + senderConfig.MailAccount);
}
catch (Exception ex)
{
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.HttpRequestFailed));
}
}
}
}