邮件模板完成

usertest
嵇文龙 4 months ago
parent 8e761723ad
commit fdb520f9c4

@ -73,6 +73,26 @@ namespace DS.Module.Core.Data
return default; return default;
} }
/// <summary>
///
/// </summary>
public T? GetOrDefault<T>(string key)
{
if (dataContext.TryGetValue(key, out var value))
{
if (value is T t)
{
return t;
}
else if (value != null)
{
return (T)Convert.ChangeType(value, typeof(T));
}
}
return default;
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

@ -168,12 +168,14 @@ namespace DS.Module.Core
} }
else if (method == HttpMethod.Post) else if (method == HttpMethod.Post)
{ {
var jsonRequest = new StringContent(JsonConvert.SerializeObject(requestParams), Encoding.UTF8, "application/json"); string json = JsonConvert.SerializeObject(requestParams);
var jsonRequest = new StringContent(json, Encoding.UTF8, "application/json");
response = await http.PostAsync(reqUri, jsonRequest); response = await http.PostAsync(reqUri, jsonRequest);
} }
else if (method == HttpMethod.Put) else if (method == HttpMethod.Put)
{ {
var jsonRequest = new StringContent(JsonConvert.SerializeObject(requestParams), Encoding.UTF8, "application/json"); string json = JsonConvert.SerializeObject(requestParams);
var jsonRequest = new StringContent(json, Encoding.UTF8, "application/json");
response = await http.PutAsync(reqUri, jsonRequest); response = await http.PutAsync(reqUri, jsonRequest);
} }
else if (method == HttpMethod.Delete) else if (method == HttpMethod.Delete)

@ -18,11 +18,11 @@
<PackageReference Include="fasterflect" Version="3.0.0" /> <PackageReference Include="fasterflect" Version="3.0.0" />
<PackageReference Include="GZY.Quartz.MUI" Version="2.6.0" /> <PackageReference Include="GZY.Quartz.MUI" Version="2.6.0" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.62" />
<PackageReference Include="LanguageExt.Core" Version="4.4.7" /> <PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="MailKit" Version="4.7.1.1" /> <PackageReference Include="MailKit" Version="4.7.1.1" />
<PackageReference Include="Mapster" Version="7.4.0" /> <PackageReference Include="Mapster" Version="7.4.0" />
<PackageReference Include="Masuit.Tools.Core" Version="2024.4.5" /> <PackageReference Include="Masuit.Tools.Core" Version="2024.5.0" />
<PackageReference Include="MediatR" Version="12.2.0" /> <PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="MediatR.Contracts" Version="2.0.1" /> <PackageReference Include="MediatR.Contracts" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.3" /> <PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.3" />
@ -31,7 +31,7 @@
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.7" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.16" /> <PackageReference Include="Microsoft.OpenApi" Version="1.6.17" />
<PackageReference Include="MimeKit" Version="4.7.1" /> <PackageReference Include="MimeKit" Version="4.7.1" />
<PackageReference Include="MiniExcel" Version="1.34.0" /> <PackageReference Include="MiniExcel" Version="1.34.0" />

@ -21,9 +21,9 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
public long TemplateId { get; set; } public long TemplateId { get; set; }
/// <summary> /// <summary>
/// 附件获取接口的URL /// 附件文件名
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "附件获取接口的URL", Length = 255, IsNullable = false)] [SugarColumn(ColumnDescription = "附件文件名", Length = 50, IsNullable = true)]
public string RequestURL { get; set; } = string.Empty; public string? FileName { get; set; }
} }
} }

@ -48,15 +48,9 @@ namespace DS.WMS.Core.Op.Entity.TaskInteraction
/// <summary> /// <summary>
/// 服务器设置ID /// 服务器设置ID
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "任务类型", IsNullable = false)] [SugarColumn(ColumnDescription = "服务器设置ID", IsNullable = false)]
public long ServerId { get; set; } public long ServerId { get; set; }
/// <summary>
/// 服务器设置
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(ServerId))]
public BusinessTaskMailServer? Server { get; set; }
/// <summary> /// <summary>
/// 接收人设置 /// 接收人设置
/// </summary> /// </summary>

@ -1,42 +0,0 @@
using DS.Module.Core.Data;
using SqlSugar;
namespace DS.WMS.Core.Op.Entity.TaskInteraction
{
/// <summary>
/// 任务邮件服务器配置
/// </summary>
[SugarTable("business_task_mail_server", "任务邮件服务器配置")]
public class BusinessTaskMailServer : BaseOrgModelV2<long>
{
/// <summary>
/// 服务器地址
/// </summary>
[SugarColumn(ColumnDescription = "服务器地址", Length = 200, IsNullable = false)]
public string Host { get; set; } = string.Empty;
/// <summary>
/// 端口号
/// </summary>
[SugarColumn(ColumnDescription = "端口号")]
public int Port { get; set; }
/// <summary>
/// 使用SSL连接
/// </summary>
[SugarColumn(ColumnDescription = "使用SSL连接", DefaultValue = "1")]
public bool UseSSL { get; set; } = true;
/// <summary>
/// 登录账号
/// </summary>
[SugarColumn(ColumnDescription = "登录账号", Length = 200, IsNullable = true)]
public string? LoginName { get; set; }
/// <summary>
/// 登录密码
/// </summary>
[SugarColumn(ColumnDescription = "登录密码", Length = 200, IsNullable = true)]
public string? Password { get; set; }
}
}

@ -1,4 +1,5 @@
using DS.Module.Core.Data; using DS.Module.Core;
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Entity.TaskInteraction; using DS.WMS.Core.Op.Entity.TaskInteraction;
namespace DS.WMS.Core.Op.Interface.TaskInteraction namespace DS.WMS.Core.Op.Interface.TaskInteraction
@ -21,5 +22,7 @@ namespace DS.WMS.Core.Op.Interface.TaskInteraction
/// <param name="businessTask">任务信息</param> /// <param name="businessTask">任务信息</param>
/// <returns></returns> /// <returns></returns>
Task TriggerAction(BusinessTask businessTask); Task TriggerAction(BusinessTask businessTask);
Task TriggerTest(TaskBaseTypeEnum taskType, long? id);
} }
} }

@ -1,9 +1,23 @@
@model DS.WMS.Core.Op.Dtos.TaskInteraction.MailTemplateModel<DS.WMS.Core.Op.Dtos.SeaExportRes> @{
@{
var item = Model.Primary; var item = Model.Primary;
} }
<style>
.parent {
position: relative;
height: 300px;
width: 300px;
}
.child {
position: absolute;
bottom: 0;
right: 0;
width: 50px;
height: 50px;
}
</style>
<h1>测试邮件-@item.MBLNO<span style="padding: 2px"></span>@item.CustomerNo</h1> <h1>测试邮件-@item.MBLNO<span style="padding: 2px"></span>@item.CustomerNo</h1>
<div> <div>
@ -14,3 +28,7 @@
<div> <div>
<span>订单创建时间:@item.CreateTime.ToString("yyyy年MM月dd日 HH:mm:ss")</span> <span>订单创建时间:@item.CreateTime.ToString("yyyy年MM月dd日 HH:mm:ss")</span>
</div> </div>
<div class="parent">
<div id="sign" class="child"></div>
</div>

@ -1,45 +0,0 @@
using DS.Module.Core;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using Microsoft.Extensions.DependencyInjection;
namespace DS.WMS.Core.Op.Method.TaskInteraction
{
public class ActionExecutor : ServiceBase
{
//任务日志服务
//readonly ITaskLogService LogService;
/// <summary>
/// 初始化
/// </summary>
/// <param name="provider"></param>
public ActionExecutor(IServiceProvider provider) : base(provider)
{
//LogService = provider.GetRequiredService<ITaskLogService>();
}
///// <summary>
///// 执行特定任务类型的邮件服务
///// </summary>
///// <param name="task">任务</param>
///// <returns></returns>
///// <exception cref="ArgumentNullException"><paramref name="task"/>为null</exception>
//public async Task<DataResult> ExecuteAsync(BusinessTask task)
//{
// ArgumentNullException.ThrowIfNull(task, nameof(task));
// var list = await TenantDb.Queryable<BusinessTaskMail>().Where(x => x.TaskType == task.TaskType && x.TaskStatus == task.TaskStatus)
// .Select(x => new
// {
// TemplateIds = x.Attachments.Select(x => x.TemplateId),
// x.Receiver,
// x.Sender,
// x.Title,
// x.Content
// }).ToListAsync();
//}
}
}

@ -1,9 +1,11 @@
using DS.Module.Core; using DS.Module.Core;
using DS.Module.Core.Data; using DS.Module.Core.Data;
using DS.WMS.Core.Op.Dtos.TaskInteraction; using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Op.Entity.TaskInteraction; using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction; using DS.WMS.Core.Op.Interface.TaskInteraction;
using DS.WMS.Core.TaskPlat; using DS.WMS.Core.TaskPlat;
using SqlSugar;
namespace DS.WMS.Core.Op.Method.TaskInteraction namespace DS.WMS.Core.Op.Method.TaskInteraction
{ {
@ -65,6 +67,28 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
await executor.ExecuteAsync(context); await executor.ExecuteAsync(context);
} }
} }
public async Task TriggerTest(TaskBaseTypeEnum taskType, long? id)
{
var task = await TenantDb.Queryable<BusinessTask>()
.Where(t => t.TaskType == taskType
//&& SqlFunc.Subqueryable<SeaExport>().Where(s => t.BusinessId == s.Id && s.BillSubmitStatus == AuditStatusEnum.Approve).Any()
)
//.Where(x => x.TaskStatus == TaskStatusEnum.Complete)
.WhereIF(id.HasValue, x => x.BusinessId == id)
.OrderByDescending(t => SqlFunc.GetRandom()).Take(1).FirstAsync();
if (task != null)
{
TaskFlowDataContext dataContext = new(
(TaskFlowDataNameConst.BusinessTask, task),
("ActionType", 1),
("Name", "订舱代理通知")
);
TaskFlowRuner taskFlow = new(TenantDb, ServiceProvider);
await taskFlow.RunWithBsno(task.TaskType, task.BusinessId, dataContext);
}
}
} }
/// <summary> /// <summary>

@ -2,17 +2,19 @@
using DS.Module.PrintModule; using DS.Module.PrintModule;
using DS.Module.SqlSugar; using DS.Module.SqlSugar;
using DS.Module.UserModule; using DS.Module.UserModule;
using DS.WMS.Core.Code.Entity;
using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.Op.Dtos.TaskInteraction; 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;
using DS.WMS.Core.Op.Interface.TaskInteraction; using DS.WMS.Core.Op.Interface.TaskInteraction;
using DS.WMS.Core.Sys.Entity; using DS.WMS.Core.Sys.Entity;
using MailKit.Net.Smtp; using HtmlAgilityPack;
using Masuit.Tools; using Masuit.Tools;
using Masuit.Tools.Systems; using Masuit.Tools.Systems;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using MimeKit;
using Newtonsoft.Json; using Newtonsoft.Json;
using RazorEngineCore; using RazorEngineCore;
using SqlSugar; using SqlSugar;
@ -47,159 +49,222 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
var logService = context.ServiceProvider.GetRequiredService<ITaskLogService>(); var logService = context.ServiceProvider.GetRequiredService<ITaskLogService>();
var seService = context.ServiceProvider.GetRequiredService<ISeaExportService>(); 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()) if (mailName.IsNullOrEmpty())
{ {
await logService.WriteLogAsync(context.TaskInfo, $"未配置【{context.TaskInfo.TaskType.GetDescription()}】任务的邮件设置"); await logService.WriteLogAsync(context.TaskInfo, $"未配置【{context.TaskInfo.TaskType.GetDescription()}】任务的邮件设置");
return; return;
} }
var mailConfig = await service.GetAsync(mailName); mailConfig = await service.GetAsync(mailName);
}
if (mailConfig == null) if (mailConfig == null)
{ {
await logService.WriteLogAsync(context.TaskInfo, $"未能获取名为【{mailName}】的邮件配置"); await logService.WriteLogAsync(context.TaskInfo, $"未能根据任务配置值获取邮件模板设置");
return; return;
} }
var result = seService.GetSeaExportInfo(context.TaskInfo.BusinessId.ToString()); 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()}数据"); await logService.WriteLogAsync(context.TaskInfo, $"未能获取Id={context.TaskInfo.BusinessId}的{context.TaskInfo.BusinessType.GetDescription()}数据");
return; return;
} }
string title, content = string.Empty;
var templateModel = new MailTemplateModel<SeaExportRes> { Primary = result.Data }; var templateModel = new MailTemplateModel<SeaExportRes> { Primary = result.Data };
IRazorEngine razorEngine = new RazorEngine(); IRazorEngine razorEngine = new RazorEngine();
try
{
var titleTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportRes>>>(mailConfig.Title); var titleTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportRes>>>(mailConfig.Title);
string title = titleTemplate.Run(x => title = await titleTemplate.RunAsync(x =>
{ {
x.Model = templateModel; x.Model = templateModel;
}); });
var contentTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportRes>>>(mailConfig.Content); var contentTemplate = razorEngine.Compile<RazorEngineTemplateBase<MailTemplateModel<SeaExportRes>>>(mailConfig.Content);
string content = contentTemplate.Run(x => content = await contentTemplate.RunAsync(x =>
{ {
x.Model = templateModel; 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) 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); await logService.WriteLogAsync(context.TaskInfo, "未设置发件人");
} return;
if (mailConfig.Sender.IsOperator)
{
senderIds.Add(templateModel.Primary.OperatorId);
}
if (mailConfig.Sender.IsCustomerService)
{
senderIds.Add(templateModel.Primary.CustomerService);
} }
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) var htmlDoc = new HtmlDocument();
message.From.Add(new MailboxAddress(sender.UserName, sender.Email)); 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) if (mailConfig.Receiver.IsCarrier)
{
receiverIds.Add(templateModel.Primary.CarrierId); receiverIds.Add(templateModel.Primary.CarrierId);
}
if (mailConfig.Receiver.IsBooking) if (mailConfig.Receiver.IsBooking)
{ receiverIds.Add(templateModel.Primary.CarrierId);
//receiverIds.Add(templateModel.Primary.CarrierId);
}
if (mailConfig.Receiver.IsYard) if (mailConfig.Receiver.IsYard)
{
receiverIds.Add(templateModel.Primary.YardId); receiverIds.Add(templateModel.Primary.YardId);
}
if (mailConfig.Receiver.IsTruck) if (mailConfig.Receiver.IsTruck)
{
receiverIds.Add(templateModel.Primary.TruckerId); receiverIds.Add(templateModel.Primary.TruckerId);
}
if (mailConfig.Receiver.IsController) if (mailConfig.Receiver.IsController)
{
receiverIds.Add(templateModel.Primary.CustomerId); receiverIds.Add(templateModel.Primary.CustomerId);
}
var receiverList = await tenantDb.Queryable<InfoClient>().Where(x => receiverIds.Contains(x.Id) && x.Email != null && x.Email != string.Empty) 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(); .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) if (mailConfig.Attachments?.Count > 0)
{ {
var multipart = new Multipart("mixed");
multipart.Add(textPart);
if (api.DefaultHeaders.Contains("Authorization")) if (api.DefaultHeaders.Contains("Authorization"))
api.DefaultHeaders.Remove("Authorization"); api.DefaultHeaders.Remove("Authorization");
api.DefaultHeaders.Add("Authorization", "Bearer " + user.GetToken()); api.DefaultHeaders.Add("Authorization", "Bearer " + user.GetToken());
long tenantId = long.Parse(user.TenantId); long tenantId = long.Parse(user.TenantId);
string requestUrl = config["TaskMail:FileBaseUrl"] + config["TaskMail:SQLPrint"];
foreach (var item in mailConfig.Attachments) foreach (var item in mailConfig.Attachments)
{ {
var req = new OpenPrintReq var req = new OpenPrintReq
{ {
ParamJsonStr = JsonConvert.SerializeObject(new { Id = context.TaskInfo.BusinessId }), ParamJsonStr = JsonConvert.SerializeObject(new { Id = context.TaskInfo.BusinessId }),
PrintType = "1", PrintType = ((int)FileFormat.PDF).ToString(),
TemplateId = item.TemplateId, TemplateId = item.TemplateId,
TenantId = tenantId TenantId = tenantId
}; };
var reqResult = await api.PostAsync<PrintResult>(item.RequestURL, req); var reqResult = await api.PostAsync<PrintResult>(requestUrl, req);
if (!reqResult.Succeeded) if (!reqResult.Succeeded)
{ {
await logService.WriteLogAsync(context.TaskInfo, $"未能获取打印API生成的文件请求地址{item.RequestURL}"); await logService.WriteLogAsync(context.TaskInfo, $"未能获取打印API生成的文件请求地址{requestUrl}");
return; return;
} }
Uri uri = new Uri(item.RequestURL);
string url = uri.Scheme + "://" + uri.Host string url = config["TaskMail:FileBaseUrl"] + @"/PrintTempFile/" + reqResult.Data.Data;
+ ((uri.Port == 80 || uri.Port == 443) ? string.Empty : ":" + uri.Port) var fileResult = await api.SendRequestAsync(HttpMethod.Get, url);
+ "//PrintTempFile//" + reqResult.Data; if (!fileResult.Succeeded)
//var attachment = new MimePart("image", "gif") {
//{ await logService.WriteLogAsync(context.TaskInfo, $"未能获取打印API生成的文件附件地址{url}");
// Content = new MimeContent(File.OpenRead(path), ContentEncoding.Default), return;
// ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
// ContentTransferEncoding = ContentEncoding.Base64,
// FileName = Path.GetFileName(path)
//};
} }
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(); dynamic[] mailParams = [new
try {
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); AttachName = x.Item1,
if (!mailConfig.Server.LoginName.IsNullOrEmpty() && !mailConfig.Server.Password.IsNullOrEmpty()) 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) catch (Exception ex)
{ {
await ex.LogAsync(db); 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
} }
} }

@ -39,7 +39,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
public async Task<DataResult<BusinessTaskMail>> GetAsync(long id) public async Task<DataResult<BusinessTaskMail>> GetAsync(long id)
{ {
var entity = await TenantDb.Queryable<BusinessTaskMail>() var entity = await TenantDb.Queryable<BusinessTaskMail>()
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Server).Includes(x => x.Attachments) .Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Attachments)
.Where(x => x.Id == id).FirstAsync(); .Where(x => x.Id == id).FirstAsync();
return DataResult<BusinessTaskMail>.Success(entity); return DataResult<BusinessTaskMail>.Success(entity);
@ -53,7 +53,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
public async Task<BusinessTaskMail> GetAsync(string name) public async Task<BusinessTaskMail> GetAsync(string name)
{ {
return await TenantDb.Queryable<BusinessTaskMail>() return await TenantDb.Queryable<BusinessTaskMail>()
.Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Server).Includes(x => x.Attachments) .Includes(x => x.Receiver).Includes(x => x.Sender).Includes(x => x.Attachments)
.Where(x => x.Name == name).FirstAsync(); .Where(x => x.Name == name).FirstAsync();
} }
@ -71,13 +71,12 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{ {
taskMail.Receiver ??= new(); taskMail.Receiver ??= new();
taskMail.Sender ??= new(); taskMail.Sender ??= new();
taskMail.Server ??= new();
taskMail = await TenantDb.InsertNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Server).ExecuteReturnEntityAsync(); taskMail = await TenantDb.InsertNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteReturnEntityAsync();
} }
else else
{ {
await TenantDb.UpdateNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Server).ExecuteCommandAsync(); await TenantDb.UpdateNav(taskMail).Include(x => x.Receiver).Include(x => x.Sender).ExecuteCommandAsync();
} }
if (taskMail.Attachments?.Count > 0) if (taskMail.Attachments?.Count > 0)
@ -113,7 +112,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
try try
{ {
await TenantDb.DeleteNav<BusinessTaskMail>(x => model.Ids.Contains(x.Id)) await TenantDb.DeleteNav<BusinessTaskMail>(x => model.Ids.Contains(x.Id))
.Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Server).Include(x => x.Attachments) .Include(x => x.Receiver).Include(x => x.Sender).Include(x => x.Attachments)
.ExecuteCommandAsync(); .ExecuteCommandAsync();
await TenantDb.Ado.CommitTranAsync(); await TenantDb.Ado.CommitTranAsync();

@ -1,4 +1,5 @@
using DS.Module.Core.Data; using DS.Module.Core.Data;
using SqlSugar;
using System.ComponentModel; using System.ComponentModel;
namespace DS.WMS.Core.Sys.Entity; namespace DS.WMS.Core.Sys.Entity;
@ -6,7 +7,7 @@ namespace DS.WMS.Core.Sys.Entity;
/// <summary> /// <summary>
/// 用户实体 /// 用户实体
/// </summary> /// </summary>
[SqlSugar.SugarTable("sys_user")] [SugarTable("sys_user")]
public class SysUser : UserTenantModel<long> public class SysUser : UserTenantModel<long>
{ {
/// <summary> /// <summary>
@ -216,4 +217,11 @@ public class SysUser : UserTenantModel<long>
/// </summary> /// </summary>
[Description("邮件签名")] [Description("邮件签名")]
public string SignatureHtml { get; set; } public string SignatureHtml { get; set; }
/// <summary>
/// 邮件签名Html代码
/// </summary>
[SugarColumn(ColumnDescription = "SignatureHtml", Length = 255, IsNullable = true)]
public string? SignatureHtml { get; set; }
} }

@ -110,3 +110,10 @@
2024-08-08 19:59:15.1322 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config 2024-08-08 19:59:15.1322 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config
2024-08-08 19:59:15.1322 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile 2024-08-08 19:59:15.1322 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile
2024-08-08 19:59:15.1461 Info Configuration initialized. 2024-08-08 19:59:15.1461 Info Configuration initialized.
2024-08-09 09:16:39.0114 Info Registered target NLog.Targets.FileTarget(Name=allfile)
2024-08-09 09:16:39.0238 Info Registered target NLog.Targets.FileTarget(Name=ownFile-web)
2024-08-09 09:16:39.0238 Info Registered target NLog.Targets.ColoredConsoleTarget(Name=console)
2024-08-09 09:16:39.0383 Info NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c. File version: 5.2.8.2366. Product version: 5.2.8+f586f1341c46fa38aaaff4c641e7f0fa7e813943. GlobalAssemblyCache: False
2024-08-09 09:16:39.0383 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config
2024-08-09 09:16:39.0383 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile
2024-08-09 09:16:39.0514 Info Configuration initialized.

@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<_PublishTargetUrl>D:\Publish\DS8\FeeApi</_PublishTargetUrl> <_PublishTargetUrl>D:\Publish\DS8\FeeApi</_PublishTargetUrl>
<History>True|2024-08-09T00:45:38.7858906Z||;True|2024-08-05T11:37:07.3133020+08:00||;True|2024-07-24T16:45:58.2272340+08:00||;True|2024-07-24T15:48:52.0128987+08:00||;True|2024-07-23T17:41:01.7494842+08:00||;True|2024-07-23T17:25:11.8773492+08:00||;True|2024-07-23T17:07:16.5460273+08:00||;True|2024-07-22T08:59:23.3235603+08:00||;True|2024-07-12T17:35:11.1225017+08:00||;True|2024-07-11T11:40:17.3581147+08:00||;True|2024-07-04T17:20:50.0175739+08:00||;True|2024-07-02T11:26:14.2092751+08:00||;True|2024-07-02T09:21:51.3513605+08:00||;True|2024-07-01T17:47:56.0407256+08:00||;True|2024-07-01T16:42:55.7374984+08:00||;True|2024-07-01T15:49:58.9266967+08:00||;True|2024-07-01T14:35:48.1117178+08:00||;True|2024-07-01T11:41:52.2969338+08:00||;True|2024-07-01T11:13:02.6561160+08:00||;True|2024-06-28T15:28:43.1470725+08:00||;True|2024-06-28T15:16:20.1999596+08:00||;True|2024-06-28T15:14:56.2534743+08:00||;True|2024-06-28T15:02:41.3033806+08:00||;True|2024-06-28T13:37:28.2462742+08:00||;True|2024-06-28T11:06:30.7400535+08:00||;True|2024-06-26T15:24:17.1939896+08:00||;True|2024-06-26T14:33:06.3530466+08:00||;True|2024-06-26T09:45:24.4055568+08:00||;True|2024-06-25T15:45:57.6052473+08:00||;True|2024-06-25T10:17:17.7408916+08:00||;False|2024-06-25T10:16:23.5639654+08:00||;False|2024-06-25T10:15:28.3857721+08:00||;False|2024-06-25T10:10:59.5536995+08:00||;False|2024-06-25T10:07:10.4050937+08:00||;True|2024-06-24T15:22:18.2672769+08:00||;True|2024-06-24T15:01:04.8153621+08:00||;False|2024-06-24T15:00:29.9618848+08:00||;True|2024-06-24T14:07:19.9401637+08:00||;False|2024-06-24T14:06:36.1250570+08:00||;True|2024-06-21T15:13:57.4273503+08:00||;True|2024-06-21T15:04:37.8218608+08:00||;True|2024-06-21T14:12:48.0266638+08:00||;True|2024-06-21T13:52:30.0950155+08:00||;True|2024-06-20T11:02:42.9508506+08:00||;True|2024-06-19T11:43:01.1899282+08:00||;True|2024-06-19T11:23:01.2938141+08:00||;True|2024-06-18T08:51:21.6222152+08:00||;True|2024-06-17T09:20:35.0804494+08:00||;True|2024-06-17T08:41:58.1319484+08:00||;True|2024-06-17T08:38:09.0137102+08:00||;True|2024-06-14T15:19:45.7395180+08:00||;True|2024-06-14T14:38:49.7094421+08:00||;True|2024-06-14T14:27:39.2815370+08:00||;True|2024-06-14T09:42:21.5397525+08:00||;True|2024-06-13T16:03:39.8475642+08:00||;True|2024-06-13T14:12:10.1725629+08:00||;True|2024-06-13T10:46:52.6971321+08:00||;True|2024-06-11T17:03:44.8328978+08:00||;True|2024-06-06T17:41:51.1810315+08:00||;True|2024-06-06T10:57:27.8273617+08:00||;True|2024-06-04T14:23:21.3742450+08:00||;True|2024-05-31T17:01:42.4717460+08:00||;True|2024-05-31T13:56:03.0734064+08:00||;True|2024-05-31T08:45:52.3549394+08:00||;True|2024-05-30T17:16:32.8907958+08:00||;True|2024-05-30T16:18:06.9957657+08:00||;True|2024-05-29T15:44:18.4051203+08:00||;True|2024-05-29T15:11:03.1518632+08:00||;True|2024-05-29T14:52:26.0823495+08:00||;True|2024-05-29T11:17:20.2245101+08:00||;True|2024-05-29T08:36:28.9569161+08:00||;True|2024-05-28T08:44:31.4427261+08:00||;False|2024-05-28T08:44:02.5254826+08:00||;True|2024-05-27T15:16:32.9413631+08:00||;True|2024-05-27T15:03:42.9803879+08:00||;True|2024-05-27T08:49:54.3933663+08:00||;True|2024-05-27T08:46:13.5862236+08:00||;True|2024-05-23T17:19:32.8154451+08:00||;True|2024-05-23T17:19:01.4587615+08:00||;True|2024-05-22T16:52:42.2166228+08:00||;True|2024-05-22T15:19:49.1773202+08:00||;True|2024-05-22T15:13:31.9485525+08:00||;True|2024-05-22T13:29:02.1355808+08:00||;True|2024-05-22T09:48:40.8753914+08:00||;True|2024-05-22T09:25:06.2068137+08:00||;True|2024-05-22T09:18:53.0759815+08:00||;True|2024-05-21T17:13:36.4091775+08:00||;True|2024-05-21T14:41:18.8486299+08:00||;True|2024-05-21T11:04:27.3649637+08:00||;</History> <History>True|2024-08-09T01:18:05.8484398Z||;True|2024-08-09T08:45:38.7858906+08:00||;True|2024-08-05T11:37:07.3133020+08:00||;True|2024-07-24T16:45:58.2272340+08:00||;True|2024-07-24T15:48:52.0128987+08:00||;True|2024-07-23T17:41:01.7494842+08:00||;True|2024-07-23T17:25:11.8773492+08:00||;True|2024-07-23T17:07:16.5460273+08:00||;True|2024-07-22T08:59:23.3235603+08:00||;True|2024-07-12T17:35:11.1225017+08:00||;True|2024-07-11T11:40:17.3581147+08:00||;True|2024-07-04T17:20:50.0175739+08:00||;True|2024-07-02T11:26:14.2092751+08:00||;True|2024-07-02T09:21:51.3513605+08:00||;True|2024-07-01T17:47:56.0407256+08:00||;True|2024-07-01T16:42:55.7374984+08:00||;True|2024-07-01T15:49:58.9266967+08:00||;True|2024-07-01T14:35:48.1117178+08:00||;True|2024-07-01T11:41:52.2969338+08:00||;True|2024-07-01T11:13:02.6561160+08:00||;True|2024-06-28T15:28:43.1470725+08:00||;True|2024-06-28T15:16:20.1999596+08:00||;True|2024-06-28T15:14:56.2534743+08:00||;True|2024-06-28T15:02:41.3033806+08:00||;True|2024-06-28T13:37:28.2462742+08:00||;True|2024-06-28T11:06:30.7400535+08:00||;True|2024-06-26T15:24:17.1939896+08:00||;True|2024-06-26T14:33:06.3530466+08:00||;True|2024-06-26T09:45:24.4055568+08:00||;True|2024-06-25T15:45:57.6052473+08:00||;True|2024-06-25T10:17:17.7408916+08:00||;False|2024-06-25T10:16:23.5639654+08:00||;False|2024-06-25T10:15:28.3857721+08:00||;False|2024-06-25T10:10:59.5536995+08:00||;False|2024-06-25T10:07:10.4050937+08:00||;True|2024-06-24T15:22:18.2672769+08:00||;True|2024-06-24T15:01:04.8153621+08:00||;False|2024-06-24T15:00:29.9618848+08:00||;True|2024-06-24T14:07:19.9401637+08:00||;False|2024-06-24T14:06:36.1250570+08:00||;True|2024-06-21T15:13:57.4273503+08:00||;True|2024-06-21T15:04:37.8218608+08:00||;True|2024-06-21T14:12:48.0266638+08:00||;True|2024-06-21T13:52:30.0950155+08:00||;True|2024-06-20T11:02:42.9508506+08:00||;True|2024-06-19T11:43:01.1899282+08:00||;True|2024-06-19T11:23:01.2938141+08:00||;True|2024-06-18T08:51:21.6222152+08:00||;True|2024-06-17T09:20:35.0804494+08:00||;True|2024-06-17T08:41:58.1319484+08:00||;True|2024-06-17T08:38:09.0137102+08:00||;True|2024-06-14T15:19:45.7395180+08:00||;True|2024-06-14T14:38:49.7094421+08:00||;True|2024-06-14T14:27:39.2815370+08:00||;True|2024-06-14T09:42:21.5397525+08:00||;True|2024-06-13T16:03:39.8475642+08:00||;True|2024-06-13T14:12:10.1725629+08:00||;True|2024-06-13T10:46:52.6971321+08:00||;True|2024-06-11T17:03:44.8328978+08:00||;True|2024-06-06T17:41:51.1810315+08:00||;True|2024-06-06T10:57:27.8273617+08:00||;True|2024-06-04T14:23:21.3742450+08:00||;True|2024-05-31T17:01:42.4717460+08:00||;True|2024-05-31T13:56:03.0734064+08:00||;True|2024-05-31T08:45:52.3549394+08:00||;True|2024-05-30T17:16:32.8907958+08:00||;True|2024-05-30T16:18:06.9957657+08:00||;True|2024-05-29T15:44:18.4051203+08:00||;True|2024-05-29T15:11:03.1518632+08:00||;True|2024-05-29T14:52:26.0823495+08:00||;True|2024-05-29T11:17:20.2245101+08:00||;True|2024-05-29T08:36:28.9569161+08:00||;True|2024-05-28T08:44:31.4427261+08:00||;False|2024-05-28T08:44:02.5254826+08:00||;True|2024-05-27T15:16:32.9413631+08:00||;True|2024-05-27T15:03:42.9803879+08:00||;True|2024-05-27T08:49:54.3933663+08:00||;True|2024-05-27T08:46:13.5862236+08:00||;True|2024-05-23T17:19:32.8154451+08:00||;True|2024-05-23T17:19:01.4587615+08:00||;True|2024-05-22T16:52:42.2166228+08:00||;True|2024-05-22T15:19:49.1773202+08:00||;True|2024-05-22T15:13:31.9485525+08:00||;True|2024-05-22T13:29:02.1355808+08:00||;True|2024-05-22T09:48:40.8753914+08:00||;True|2024-05-22T09:25:06.2068137+08:00||;True|2024-05-22T09:18:53.0759815+08:00||;True|2024-05-21T17:13:36.4091775+08:00||;True|2024-05-21T14:41:18.8486299+08:00||;True|2024-05-21T11:04:27.3649637+08:00||;</History>
<LastFailureDetails /> <LastFailureDetails />
</PropertyGroup> </PropertyGroup>
</Project> </Project>

@ -1,4 +1,5 @@
using DS.Module.Core; using System.Net;
using DS.Module.Core;
using DS.WMS.Core.Op.Entity.TaskInteraction; using DS.WMS.Core.Op.Entity.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction; using DS.WMS.Core.Op.Interface.TaskInteraction;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -21,6 +22,31 @@ namespace DS.WMS.OpApi.Controllers
this.service = service; this.service = service;
} }
/// <summary>
/// 运行测试
/// </summary>
/// <param name="actionManager"></param>
/// <param name="taskype">任务类型</param>
/// <param name="id">业务ID</param>
/// <returns></returns>
[HttpGet, Route("RunTest")]
public async Task<IActionResult> RunTestAsync([FromServices] IActionManagerService actionManager,
[FromQuery] TaskBaseTypeEnum taskype, [FromQuery] long? id)
{
HttpStatusCode statusCode;
try
{
await actionManager.TriggerTest(taskype, id);
statusCode = HttpStatusCode.NoContent;
}
catch
{
statusCode = HttpStatusCode.InternalServerError;
}
return new StatusCodeResult((int)statusCode);
}
/// <summary> /// <summary>
/// 获取分页列表 /// 获取分页列表
/// </summary> /// </summary>

@ -104,5 +104,12 @@
"ShippingOrderCompare": { "ShippingOrderCompare": {
"Url": "http://47.104.73.97:7115/api/TaskShippingOrderCompare/ExcuteShippingOrderCompare", "Url": "http://47.104.73.97:7115/api/TaskShippingOrderCompare/ExcuteShippingOrderCompare",
"ResultUrl": "http://47.104.73.97:7115/api/TaskShippingOrderCompare/CompareResult" "ResultUrl": "http://47.104.73.97:7115/api/TaskShippingOrderCompare/CompareResult"
},
"TaskMail": {
"FileBaseUrl": "http://118.190.144.189:3008",
"JsonPrint": "/printApi/OpenPrint/GetOpenJsonPrintInfoAsync",
"JsonPrintByCode": "/printApi/OpenPrint/GetOpenJsonPrintInfoByTemplateCode",
"SQLPrint": "/printApi/OpenPrint/GetOpenSqlPrintInfo",
"MailApiUrl": "http://47.104.73.97:8801/mail/send"
} }
} }

Loading…
Cancel
Save