|
|
|
@ -2,17 +2,19 @@
|
|
|
|
|
using DS.Module.PrintModule;
|
|
|
|
|
using DS.Module.SqlSugar;
|
|
|
|
|
using DS.Module.UserModule;
|
|
|
|
|
using DS.WMS.Core.Code.Entity;
|
|
|
|
|
using DS.WMS.Core.Info.Entity;
|
|
|
|
|
using DS.WMS.Core.Op.Dtos;
|
|
|
|
|
using DS.WMS.Core.Op.Dtos.TaskInteraction;
|
|
|
|
|
using DS.WMS.Core.Op.Entity.TaskInteraction;
|
|
|
|
|
using DS.WMS.Core.Op.Interface;
|
|
|
|
|
using DS.WMS.Core.Op.Interface.TaskInteraction;
|
|
|
|
|
using DS.WMS.Core.Sys.Entity;
|
|
|
|
|
using MailKit.Net.Smtp;
|
|
|
|
|
using HtmlAgilityPack;
|
|
|
|
|
using Masuit.Tools;
|
|
|
|
|
using Masuit.Tools.Systems;
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using MimeKit;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using RazorEngineCore;
|
|
|
|
|
using SqlSugar;
|
|
|
|
@ -47,159 +49,222 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
|
|
|
|
|
var logService = context.ServiceProvider.GetRequiredService<ITaskLogService>();
|
|
|
|
|
var seService = context.ServiceProvider.GetRequiredService<ISeaExportService>();
|
|
|
|
|
|
|
|
|
|
var mailName = context.AdditionalData["MailName"] as string;
|
|
|
|
|
var config = context.ServiceProvider.GetRequiredService<IConfiguration>();
|
|
|
|
|
|
|
|
|
|
BusinessTaskMail? mailConfig = null;
|
|
|
|
|
if (context.AdditionalData.TryGetValue(nameof(BusinessTaskMail.Id), out var id))
|
|
|
|
|
{
|
|
|
|
|
if (id == null)
|
|
|
|
|
{
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未配置【{context.TaskInfo.TaskType.GetDescription()}】任务的邮件设置");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var idVal = (long)Convert.ChangeType(id, typeof(long));
|
|
|
|
|
mailConfig = (await service.GetAsync(idVal)).Data;
|
|
|
|
|
}
|
|
|
|
|
else if (context.AdditionalData.TryGetValue(nameof(BusinessTaskMail.Name), out var name))
|
|
|
|
|
{
|
|
|
|
|
var mailName = name as string;
|
|
|
|
|
if (mailName.IsNullOrEmpty())
|
|
|
|
|
{
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未配置【{context.TaskInfo.TaskType.GetDescription()}】任务的邮件设置");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var mailConfig = await service.GetAsync(mailName);
|
|
|
|
|
mailConfig = await service.GetAsync(mailName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mailConfig == null)
|
|
|
|
|
{
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未能获取名为【{mailName}】的邮件配置");
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未能根据任务配置值获取邮件模板设置");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var result = seService.GetSeaExportInfo(context.TaskInfo.BusinessId.ToString());
|
|
|
|
|
if (!result.Succeeded)
|
|
|
|
|
if (!result.Succeeded || result.Data == null)
|
|
|
|
|
{
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未能获取Id={context.TaskInfo.BusinessId}的{context.TaskInfo.BusinessType.GetDescription()}数据");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string title, content = string.Empty;
|
|
|
|
|
var templateModel = new MailTemplateModel<SeaExportRes> { Primary = result.Data };
|
|
|
|
|
IRazorEngine razorEngine = new RazorEngine();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var titleTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportRes>>>(mailConfig.Title);
|
|
|
|
|
string title = titleTemplate.Run(x =>
|
|
|
|
|
title = await titleTemplate.RunAsync(x =>
|
|
|
|
|
{
|
|
|
|
|
x.Model = templateModel;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var contentTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportRes>>>(mailConfig.Content);
|
|
|
|
|
string content = contentTemplate.Run(x =>
|
|
|
|
|
content = await contentTemplate.RunAsync(x =>
|
|
|
|
|
{
|
|
|
|
|
x.Model = templateModel;
|
|
|
|
|
});
|
|
|
|
|
var textPart = new TextPart("plain") { Text = content };
|
|
|
|
|
var message = new MimeMessage
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Subject = title,
|
|
|
|
|
};
|
|
|
|
|
await ex.LogAsync(db);
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"渲染邮件模板({mailConfig.Id})时出错,请检查模板是否有语法错误");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置发件人
|
|
|
|
|
List<long> senderIds = new List<long>();
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
senderIds.Add(templateModel.Primary.SaleId);
|
|
|
|
|
}
|
|
|
|
|
if (mailConfig.Sender.IsOperator)
|
|
|
|
|
{
|
|
|
|
|
senderIds.Add(templateModel.Primary.OperatorId);
|
|
|
|
|
}
|
|
|
|
|
if (mailConfig.Sender.IsCustomerService)
|
|
|
|
|
{
|
|
|
|
|
senderIds.Add(templateModel.Primary.CustomerService);
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, "未设置发件人");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (mailConfig.Sender.IsVouchingClerk)
|
|
|
|
|
var senderConfig = await tenantDb.Queryable<CodeUserEmail>().FirstAsync(x => x.CreateBy == senderId);
|
|
|
|
|
if (senderConfig == null)
|
|
|
|
|
{
|
|
|
|
|
senderIds.Add(templateModel.Primary.Doc);
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"发件人用户:{sender.UserName} 未设置SMTP发件信息");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var senderList = await db.Queryable<SysUser>().Where(x => senderIds.Contains(x.Id) && x.Email != null && x.Email != string.Empty)
|
|
|
|
|
.Select(x => new { x.UserName, x.UserEnName, x.Email }).ToListAsync();
|
|
|
|
|
foreach (var sender in senderList)
|
|
|
|
|
message.From.Add(new MailboxAddress(sender.UserName, sender.Email));
|
|
|
|
|
|
|
|
|
|
//插入发件人签名
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
//设置收件人
|
|
|
|
|
List<long> receiverIds = new List<long>();
|
|
|
|
|
List<long> receiverIds = [];
|
|
|
|
|
if (mailConfig.Receiver.IsCarrier)
|
|
|
|
|
{
|
|
|
|
|
receiverIds.Add(templateModel.Primary.CarrierId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mailConfig.Receiver.IsBooking)
|
|
|
|
|
{
|
|
|
|
|
//receiverIds.Add(templateModel.Primary.CarrierId);
|
|
|
|
|
}
|
|
|
|
|
receiverIds.Add(templateModel.Primary.CarrierId);
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
foreach (var item in receiverList)
|
|
|
|
|
message.To.Add(new MailboxAddress(item.ShortName, item.Email));
|
|
|
|
|
|
|
|
|
|
var attachmentList = mailConfig.Attachments == null ? [] : new List<Tuple<string, string>>(mailConfig.Attachments.Count);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//需要上传附件
|
|
|
|
|
if (mailConfig.Attachments?.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var multipart = new Multipart("mixed");
|
|
|
|
|
multipart.Add(textPart);
|
|
|
|
|
|
|
|
|
|
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 = context.TaskInfo.BusinessId }),
|
|
|
|
|
PrintType = "1",
|
|
|
|
|
PrintType = ((int)FileFormat.PDF).ToString(),
|
|
|
|
|
TemplateId = item.TemplateId,
|
|
|
|
|
TenantId = tenantId
|
|
|
|
|
};
|
|
|
|
|
var reqResult = await api.PostAsync<PrintResult>(item.RequestURL, req);
|
|
|
|
|
var reqResult = await api.PostAsync<PrintResult>(requestUrl, req);
|
|
|
|
|
if (!reqResult.Succeeded)
|
|
|
|
|
{
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未能获取打印API生成的文件,请求地址:{item.RequestURL}");
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未能获取打印API生成的文件,请求地址:{requestUrl}");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Uri uri = new Uri(item.RequestURL);
|
|
|
|
|
string url = uri.Scheme + "://" + uri.Host
|
|
|
|
|
+ ((uri.Port == 80 || uri.Port == 443) ? string.Empty : ":" + uri.Port)
|
|
|
|
|
+ "//PrintTempFile//" + reqResult.Data;
|
|
|
|
|
//var attachment = new MimePart("image", "gif")
|
|
|
|
|
//{
|
|
|
|
|
// Content = new MimeContent(File.OpenRead(path), ContentEncoding.Default),
|
|
|
|
|
// ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
|
|
|
|
|
// ContentTransferEncoding = ContentEncoding.Base64,
|
|
|
|
|
// FileName = Path.GetFileName(path)
|
|
|
|
|
//};
|
|
|
|
|
|
|
|
|
|
string url = config["TaskMail:FileBaseUrl"] + @"/PrintTempFile/" + reqResult.Data.Data;
|
|
|
|
|
var fileResult = await api.SendRequestAsync(HttpMethod.Get, url);
|
|
|
|
|
if (!fileResult.Succeeded)
|
|
|
|
|
{
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"未能获取打印API生成的文件,附件地址:{url}");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
message.Body = textPart;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var client = new SmtpClient();
|
|
|
|
|
try
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
client.Connect(mailConfig.Server.Host, mailConfig.Server.Port, mailConfig.Server.UseSSL);
|
|
|
|
|
if (!mailConfig.Server.LoginName.IsNullOrEmpty() && !mailConfig.Server.Password.IsNullOrEmpty())
|
|
|
|
|
AttachName = x.Item1,
|
|
|
|
|
AttachContent = x.Item2
|
|
|
|
|
}).ToList()
|
|
|
|
|
}];
|
|
|
|
|
var mailResult = await api.SendRequestAsync(HttpMethod.Post, config["TaskMail:MailApiUrl"], mailParams);
|
|
|
|
|
if (mailResult.Data.IsSuccessStatusCode)
|
|
|
|
|
{
|
|
|
|
|
client.Authenticate(mailConfig.Server.LoginName, mailConfig.Server.Password);
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"已发邮件(委托单:{templateModel.Primary.CustomerNo}),收件人:"
|
|
|
|
|
+ string.Join(",", receiverList.Select(x => x.Email)) + "发件人:" + senderConfig.MailAccount);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await logService.WriteLogAsync(context.TaskInfo, $"邮件发送失败(委托单:{templateModel.Primary.CustomerNo}),收件人:"
|
|
|
|
|
+ string.Join(",", receiverList.Select(x => x.Email)) + "发件人:" + senderConfig.MailAccount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client.Send(message);
|
|
|
|
|
client.Disconnect(true);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
await ex.LogAsync(db);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
client?.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 文件格式
|
|
|
|
|
/// </summary>
|
|
|
|
|
public enum FileFormat
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// PDF
|
|
|
|
|
/// </summary>
|
|
|
|
|
PDF = 1,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Excel
|
|
|
|
|
/// </summary>
|
|
|
|
|
Xlsx = 2,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Word
|
|
|
|
|
/// </summary>
|
|
|
|
|
Docx = 3
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|