订舱委托模板

usertest
嵇文龙 3 months ago
parent ad36866165
commit f411cf08a8

@ -33,7 +33,7 @@
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content> </Content>
<Content Include="Op\Templates\MailTemplate.cshtml"> <Content Include="Op\Templates\订舱委托.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content> </Content>

@ -30,6 +30,8 @@ public class SeaExportRes
/// </summary> /// </summary>
public OpBusinessYardRes? YardInfo { get; set; } public OpBusinessYardRes? YardInfo { get; set; }
/// <summary> /// <summary>
/// 主键Id /// 主键Id
/// </summary> /// </summary>
@ -546,7 +548,7 @@ public class SeaExportRes
/// </summary> /// </summary>
public long ForwarderId { get; set; } public long ForwarderId { get; set; }
/// <summary> /// <summary>
/// 货代公司 /// 货代公司(订舱口)
/// </summary> /// </summary>
public string Forwarder { get; set; } public string Forwarder { get; set; }

@ -1,4 +1,5 @@
using System.Dynamic; using System.Collections.ObjectModel;
using System.Dynamic;
namespace DS.WMS.Core.Op.Entity namespace DS.WMS.Core.Op.Entity
{ {
@ -22,12 +23,58 @@ namespace DS.WMS.Core.Op.Entity
/// </summary> /// </summary>
public List<FileAttachment>? FileAttachments { get; set; } public List<FileAttachment>? FileAttachments { get; set; }
/// <summary>
/// 发件人
/// </summary>
public MailSender Sender { get; set; }
/// <summary>
/// 收件人
/// </summary>
public List<MailReceiver> Receivers { get; set; }
/// <summary>
/// 当前业务联系人
/// </summary>
public string Contacts => Receivers == null ? string.Empty : string.Join(",", Receivers.Select(x => x.DisplayName));
/// <summary> /// <summary>
/// 主要数据项 /// 主要数据项
/// </summary> /// </summary>
public dynamic Primary { get; set; } = new ExpandoObject(); public dynamic Primary { get; set; } = new ExpandoObject();
} }
public class MailSender
{
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 邮件地址
/// </summary>
public string MailAddress { get; set; }
/// <summary>
/// 个人签名内容
/// </summary>
public string? SignatureHtml { get; set; }
}
public class MailReceiver
{
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 邮件地址
/// </summary>
public string MailAddress { get; set; }
}
/// <summary> /// <summary>
/// 文件附件 /// 文件附件
/// </summary> /// </summary>

@ -2,6 +2,9 @@
namespace DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor.SpaceRelease namespace DS.WMS.Core.Op.Method.TaskInteraction.ActionExecutor.SpaceRelease
{ {
/// <summary>
/// 放舱-转发BC
/// </summary>
public class RelayBCActionExecutor : DefaultActionExecutor public class RelayBCActionExecutor : DefaultActionExecutor
{ {
public override async Task ExecuteAsync(ActionExecutionContext context) public override async Task ExecuteAsync(ActionExecutionContext context)

@ -62,22 +62,6 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
ArgumentNullException.ThrowIfNull(mailConfig, nameof(mailConfig)); ArgumentNullException.ThrowIfNull(mailConfig, nameof(mailConfig));
ArgumentNullException.ThrowIfNull(templateModel, nameof(templateModel)); ArgumentNullException.ThrowIfNull(templateModel, nameof(templateModel));
string title, content = string.Empty;
var razorEngine = new RazorEngine();
try
{
string key1 = mailConfig.Id + "-" + nameof(mailConfig.Title);
title = await RenderTemplateAsync(key1, mailConfig.Title, templateModel, razorEngine);
string key2 = mailConfig.Id + "-" + nameof(mailConfig.Content);
content = await RenderTemplateAsync(key2, mailConfig.Content, templateModel, razorEngine);
}
catch (Exception ex)
{
await ex.LogAsync(Db);
return DataResult.Failed($"渲染邮件模板({mailConfig.Id})时出错,请检查模板是否有语法错误");
}
var order = await TenantDb.Queryable<SeaExport>().Where(x => x.Id == templateModel.BusinessId) var order = await TenantDb.Queryable<SeaExport>().Where(x => x.Id == templateModel.BusinessId)
.Select(x => new .Select(x => new
{ {
@ -108,27 +92,17 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
else if (mailConfig.Sender.IsVouchingClerk) else if (mailConfig.Sender.IsVouchingClerk)
senderId = order.Doc; senderId = order.Doc;
var sender = await Db.Queryable<SysUser>().Where(x => x.Id == senderId).Select(x => new { x.UserName, x.SignatureHtml }).FirstAsync(); templateModel.Sender = await Db.Queryable<SysUser>().Where(x => x.Id == senderId).Select(x => new MailSender
if (sender == null) {
DisplayName = x.UserName,
SignatureHtml = x.SignatureHtml
}).FirstAsync();
if (templateModel.Sender == null)
return DataResult.Failed("未设置发件人"); return DataResult.Failed("未设置发件人");
var senderConfig = await TenantDb.Queryable<CodeUserEmail>().FirstAsync(x => x.CreateBy == senderId); var senderConfig = await TenantDb.Queryable<CodeUserEmail>().FirstAsync(x => x.CreateBy == senderId);
if (senderConfig == null) if (senderConfig == null)
return DataResult.Failed($"发件人用户:{sender.UserName} 未设置SMTP发件信息"); return DataResult.Failed($"发件人用户:{templateModel.Sender.DisplayName} 未设置SMTP发件信息");
//插入发件人签名
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(content);
var node = htmlDoc.GetElementbyId("sign");
if (node != null)
node.InnerHtml = sender.SignatureHtml;
using (StringWriter writer = new())
{
htmlDoc.Save(writer);
content = writer.ToString();
writer.Close();
}
//设置抄送人 //设置抄送人
List<long> ccIds = []; List<long> ccIds = [];
@ -162,9 +136,39 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (mailConfig.Receiver.IsController) if (mailConfig.Receiver.IsController)
receiverTypes.Add("controller"); receiverTypes.Add("controller");
var receiverList = await TenantDb.Queryable<BusinessOrderContact>().Where(x => receiverTypes.Contains(x.CustomerType) templateModel.Receivers = await TenantDb.Queryable<BusinessOrderContact>().Where(x => receiverTypes.Contains(x.CustomerType)
&& x.Email != null && x.Email != string.Empty && x.BusinessId == templateModel.BusinessId && x.BusinessType == templateModel.BusinessType) && x.Email != null && x.Email != string.Empty && x.BusinessId == templateModel.BusinessId && x.BusinessType == templateModel.BusinessType)
.Select(x => new { x.Name, x.Email }).ToListAsync(); .Select(x => new MailReceiver { DisplayName = x.Name, MailAddress = x.Email }).ToListAsync();
string title, content = string.Empty;
var razorEngine = new RazorEngine();
try
{
string key1 = mailConfig.Id + "-" + nameof(mailConfig.Title);
title = await RenderTemplateAsync(key1, mailConfig.Title, templateModel, razorEngine);
string key2 = mailConfig.Id + "-" + nameof(mailConfig.Content);
content = await RenderTemplateAsync(key2, mailConfig.Content, templateModel, razorEngine);
}
catch (Exception ex)
{
await ex.LogAsync(Db);
return DataResult.Failed($"渲染邮件模板({mailConfig.Id})时出错,请检查模板是否有语法错误");
}
//插入发件人签名
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(content);
var node = htmlDoc.GetElementbyId("sign");
if (node != null)
node.InnerHtml = templateModel.Sender.SignatureHtml;
using (StringWriter writer = new())
{
htmlDoc.Save(writer);
content = writer.ToString();
writer.Close();
}
var attachmentList = mailConfig.Attachments == null ? [] : new List<Tuple<string, string>>(mailConfig.Attachments.Count); var attachmentList = mailConfig.Attachments == null ? [] : new List<Tuple<string, string>>(mailConfig.Attachments.Count);
try try
@ -222,13 +226,14 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
} }
} }
string sendTo = string.Join(",", templateModel.Receivers.Select(x => x.MailAddress));
dynamic[] mailParams = [new dynamic[] mailParams = [new
{ {
SendTo = string.Join(",", receiverList.Select(x => x.Email)), SendTo = sendTo,
Title = title, Title = title,
Body = content, Body = content,
CCTo = string.Join(",", ccList), CCTo = string.Join(",", ccList),
ShowName = senderConfig.ShowName.IsNullOrEmpty() ? sender.UserName : senderConfig.ShowName, ShowName = senderConfig.ShowName.IsNullOrEmpty() ? templateModel.Sender.DisplayName : senderConfig.ShowName,
Account = senderConfig.MailAccount, Account = senderConfig.MailAccount,
senderConfig.Password, senderConfig.Password,
Server = senderConfig.SmtpServer, Server = senderConfig.SmtpServer,
@ -245,11 +250,11 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (mailResult.Data.IsSuccessStatusCode) if (mailResult.Data.IsSuccessStatusCode)
{ {
return DataResult.Successed($"已发邮件(委托单:{order.CustomerNo}),收件人:" return DataResult.Successed($"已发邮件(委托单:{order.CustomerNo}),收件人:"
+ string.Join(",", receiverList.Select(x => x.Email)) + "发件人:" + senderConfig.MailAccount); + string.Join(",", sendTo) + "发件人:" + senderConfig.MailAccount);
} }
return DataResult.Failed($"邮件发送失败API返回状态为{(int)mailResult.Data.StatusCode} {mailResult.Data.StatusCode}" return DataResult.Failed($"邮件发送失败API返回状态为{(int)mailResult.Data.StatusCode} {mailResult.Data.StatusCode}"
+ $"(委托单:{order.CustomerNo}),收件人:" + string.Join(",", receiverList.Select(x => x.Email)) + "发件人:" + senderConfig.MailAccount); + $"(委托单:{order.CustomerNo}),收件人:" + string.Join(",", sendTo) + "发件人:" + senderConfig.MailAccount);
} }
catch (Exception ex) catch (Exception ex)
{ {

@ -1,35 +0,0 @@
@* @model DS.WMS.Core.Op.Entity.MailTemplateModel<DS.WMS.Core.Op.Dtos.SeaExportRes> *@
@{
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>
<div>
<span>预计开船日期:@item.ETD</span>
<span>预计抵达日期:@item.ETA</span>
</div>
<hr />
<div>
<span>订单创建时间:@item.CreateTime.ToString("yyyy年MM月dd日 HH:mm:ss")</span>
</div>
<div class="parent">
<div id="sign" class="child"></div>
</div>

@ -0,0 +1,107 @@
@* @model DS.WMS.Core.Op.Entity.MailTemplateModel<DS.WMS.Core.Op.Dtos.SeaExportRes> *@
@{
var item = Model.Primary;
}
<style>
.parent {
position: relative;
height: 300px;
width: 300px;
}
.child {
position: absolute;
bottom: 0;
right: 0;
width: 50px;
height: 50px;
}
.title {
background-color: darkblue;
color: whitesmoke;
font-size: 20px;
font-weight: 300;
}
</style>
<span>*** Auto Email, please reply to all (delete sender Admin)!If only reply to sender, we will not be able to find and deal with it! ***</span>
Dear @Model.Contacts
<div class="title">
RE: BOOKING - JOB NO.
</div>
请查看附件中的订舱委托请2小时内先行回复订舱号给我们并帮忙催促船东尽快放舱如下信息同订舱委托一致便于您查阅
CARRIER@item.Carrier
S/QXX
ETD : @item.ETD
POL: @item.LoadPort
POD: @item.DischargePort
FPOD: @item.DeliveryPlace
VOL: XX
Commdity: XX取中文品名
HS CODE: @item.HSCode
POD FREE TIME
REMARK
(取供应商备注)
此票订舱我司对接同事的联系方式如下,任何问题请及时跟我们沟通,谢谢!
<table>
<thead>
<tr>
<th>CN Name</th>
<th>Name</th>
<th>Tel No.</th>
<th>Mobile/Wechat/QQ</th>
<th>Email</th>
<th>Position</th>
</tr>
</thead>
<tbody>
<tr>
<td>邵 芳</td>
<td>Candy</td>
<td>0532-80688387</td>
<td>13375570007 2853083550</td>
<td>candy@sunniness.net</td>
<td>Cooperation</td>
</tr>
<tr>
<td>魏涛</td>
<td>Wilson</td>
<td>0532-80688353</td>
<td>13969858993 2853083555</td>
<td>ope@sunniness.net</td>
<td>OP manager</td>
</tr>
<tr>
<td>徐平平</td>
<td>Cathy</td>
<td>0532-80688350</td>
<td>13969662965 2853083551</td>
<td>opg@sunniness.net</td>
<td>Document</td>
</tr>
</tbody>
</table>
<div class="parent">
<div id="sign" class="child">
@* Tks + Brgds
Candy SHAO 邵芳 (此处用当票操作的信息)
General Manager | SUNNINESS LOGISTICS CO.,LTD.
TEL: +86-0532-80688387 |MB./We chat: +86-18866622731|QQ:2853083553 | Email:candy@sunniness.net *@
</div>
</div>
@* 此邮件模板是订舱委托推送的邮件模板,在商务订单审核通过后,自动生成,并推送:
1蓝色是调取系统数据、红色是醒目提醒
2订舱委托PDF格式作为附件一起发出
3邮件发给订舱代理联系人抄送我司销售/客服和操作/单证;未勾选推送的订舱代理,仅推送我司干系人! *@
Loading…
Cancel
Save