在系统处理中,有时候需要发送邮件通知用户,如新增用户的邮件确认,密码找回,以及常规订阅消息、通知等内容处理,都可以通过邮件的方式进行处理。本篇随笔介绍结合VUE+Element 前端,实现系统的邮件参数配置管理,以及基于邮件模板的方式进行邮件的发送。

1、邮件参数的配置管理

邮件参数一般需要配置如用户名、密码、邮件地址,显示名称,以及其他邮件所需的必要配置,一般我们可以通过界面管理的方式进行常规的参数配置,如下界面所示。

其中的登录密码,现在一般是授权登录密码,而不是原始的账号密码了。以163为例,可以在设置中添加一个授权密码。

前端参数的配置管理,我们构建一个Api类,用于调用ABP后端的Api接口,如下所示。

查看窗体中显示邮件参数数据的代码如下所示。

    showAbpEmail() {
this.resetForm('emailForm')
setting.GetEmailSettingsForApplication().then(data => {
if (data.result) {
Object.assign(this.abpEmailForm, data.result)
}
this.isAbpEmail = true // 编辑状态
})
},

2、ABP后端邮件的发送处理

系统参数配置完成后,我们需要根据这些邮件参数进行邮件的发送,ABP框架基于.net core 的实现,我们发送邮件,需要添加一个Abp.MailKit的依赖,如下所示。

然后在模块的依赖上,添加对应的AbpMailkitModule的依赖即可。

一般来说,我们发送邮件,还需要重写DefaultMailKitSmtpBuilder的配置处理项,以便自定义发送处理过程。

    /// <summary>
/// 重写默认的SmtpBuilder类
/// </summary>
public class MyMailKitSmtpBuilder : DefaultMailKitSmtpBuilder
{
private readonly ISmtpEmailSenderConfiguration _smtpEmailSenderConfiguration;
private readonly IAbpMailKitConfiguration _abpMailKitConfiguration;
public MyMailKitSmtpBuilder(ISmtpEmailSenderConfiguration smtpEmailSenderConfiguration, IAbpMailKitConfiguration abpMailKitConfiguration)
: base(smtpEmailSenderConfiguration, abpMailKitConfiguration)
{
_smtpEmailSenderConfiguration = smtpEmailSenderConfiguration;
_abpMailKitConfiguration = abpMailKitConfiguration;
} /// <summary>
/// 配置发送处理
/// </summary>
/// <param name="client"></param>
protected override void ConfigureClient(SmtpClient client)
{
client.CheckCertificateRevocation = false;
client.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; client.Connect(_smtpEmailSenderConfiguration.Host, _smtpEmailSenderConfiguration.Port, GetSecureSocketOption()); if (_smtpEmailSenderConfiguration.UseDefaultCredentials)
{
return;
} var username = _smtpEmailSenderConfiguration.UserName;
var password = _smtpEmailSenderConfiguration.Password;
//password = SimpleStringCipher.Instance.Decrypt(originalPass);//如果不重写自定义配置MySmtpEmailSenderConfiguration,那么密码需要解密
client.Authenticate(username, password); //base.ConfigureClient(client);
}
}

但是由于基类处理中,默认的邮件配置密码是直接从数据库读取信息的,没有进行加密,如基类SmtpEmailSenderConfiguration的实现如下。

但是我们应用程序的设置信息,密码是经过加密过的,因此需要重写这个配置项,进行对应的密码解密。

    /// <summary>
/// 邮件发送参数配置类
/// </summary>
public class MySmtpEmailSenderConfiguration : SmtpEmailSenderConfiguration
{
public MySmtpEmailSenderConfiguration(ISettingManager settingManager) : base(settingManager)
{ } /// <summary>
/// 重写密码处理,需要解密密码
/// </summary>
public override string Password => SimpleStringCipher.Instance.Decrypt(GetNotEmptySettingValue(EmailSettingNames.Smtp.Password));
}

最后,在Module中初始化中处理下对应的自定义发送和自定义配置项的处理类。

这样默认注入的发送邮件的接口就正常了,我们接下来就是根据邮件的模板进行内容发送即可。

3、邮件模板的处理

一般的邮件模板,是一个独立的文件方式,文件中定义一些预设的内容,然后实际处理的时候,替换这些变量即可。

邮件模板的内容替换,我喜欢用基于模板引擎的方式处理变量的替换,一般我用NVelocity来进行处理。

我在早期介绍过一些关于NVelocity的知识,需要可以参考:

使用NVelocity生成内容的几种方式

强大的模板引擎开源软件NVelocity》

Database2Sharp版本更新之自定义模板生成 》

使用NVelocity0.5实现服务器端页面自动生成 》

例如,我在文本中定义一个连接:http://www.iqidi.com/h5/EmailValidate?callback=${callback} 其中${callback} 就是变量定义,可以在运行中进行变量替换的。

我们在Host项目中定义一些邮件文件模板,如下所示。

然后在使用的应用服务类中注入对应的邮件发送接口以供使用。

具体的邮件发送,就是读取模板内容,进行替换变量,然后调用接口进行邮件的发送即可。

        /// <summary>
/// 发送校验的电子邮件
/// </summary>
/// <returns></returns>
public async Task SendEmailValidate(SendEmailActivationLinkDto input)
{
var user = await GetUserByChecking(input.EmailAddress);
//user.SetNewEmailConfirmationCode(); #region 根据模板生成邮件正文 //使用相对路径进行构造处理
string template = string.Format("/UploadFiles/Email/EmailValidate.html");
var helper = new NVelocityHelper(template);
//${标题} ${内容} ${称呼} ${日期}
var tilte = "邮箱验证通知";
helper.AddKeyValue("title", tilte);
helper.AddKeyValue("callname", "");
helper.AddKeyValue("date", DateTime.Now.ToLongDateString()); //邮箱校验码
var callback = Guid.NewGuid().ToString();
helper.AddKeyValue("callback", callback); var html = helper.ExecuteString(); #endregion #region 构建邮件内容对象 发送邮件
string toEmail = "wuhuacong@163.com"; await _emailSender.SendAsync(new System.Net.Mail.MailMessage
{
To = { toEmail },
Subject = tilte,
Body = html,
IsBodyHtml = true
}); #endregion LogHelper.Logger.Info(string.Format("校验邮件发送给:{0}, {1}", toEmail, "发送邮件成功"));
}

为了处理模板内容的方便,我们把规则放在辅助类 NVelocityHelper 中处理即可。

上面就是整个发送模板邮件的过程代码了。

发送邮件成功后,我们可以在邮箱中查看到对应的邮件,我们一般根据自己的业务需要定义不同的邮件模板即可。

邮件发送成功后,查看邮件效果如下所示。

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理的更多相关文章

  1. 循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

    在我们做应用系统的时候,往往都会涉及图表的展示,综合的图表展示能够给客户带来视觉的享受和数据直观体验,同时也是增强客户认同感的举措之一.基于图表的处理,我们一般往往都是利用对应第三方的图表组件,然后在 ...

  2. 循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

    在前面随笔<循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理>中介绍了在Vue + Element整合框架中,实现了动态菜单和动态路由的处理,从而可以根据 ...

  3. 循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理

    在我们一般开发的系统界面里面,列表页面是一个非常重要的综合展示界面,包括有条件查询.列表展示和分页处理,以及对每项列表内容可能进行的转义处理,本篇随笔介绍基于Vue +Element基础上实现表格列表 ...

  4. 循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

    在我们开发BS页面的时候,往往需要了解常规界面组件的使用,小到最普通的单文本输入框.多文本框.下拉列表,以及按钮.图片展示.弹出对话框.表单处理.条码二维码等等,本篇随笔基于普通表格业务的展示录入的场 ...

  5. 循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用

    在我前面随笔<循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用>里面曾经介绍过一些常规的界面组件的处理,主要介绍到单文本输入框.多文本框.下拉列 ...

  6. 循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

    我们开发的系统,一般可以不用考虑语言国际化的问题,大多数系统一般是给本国人使用的,而且直接使用中文开发界面会更加迅速 一些,不过框架最好能够支持国际化的处理,以便在需要的时候,可以花点时间来实现多语言 ...

  7. 循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理

    VUE+Element 前端是一个纯粹的前端处理,前面介绍了很多都是Vue+Element开发的基础,从本章随笔开始,就需要进入深水区了,需要结合ABP框架使用(如果不知道,请自行补习一下我的随笔:A ...

  8. 循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

    在前面随笔<循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理>介绍了一个系统最初接触到的前端登录处理的实现,但往往对整个系统来说,一般会有很多业务对 ...

  9. 循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

    在前面随笔<循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理>简单的介绍了一个结合ABP后端的登陆接口实现前端系统登陆的功能,本篇随笔继续深化这一主 ...

随机推荐

  1. PyQt(Python+Qt)学习随笔:Qt Designer中怎么给toolBar添加按钮

    在Designer中创建了一个MainWindow窗体,当想在其中的toolBar中添加toolButton时发现怎么也放不上去,最终才发现toolBar中的按钮只能通过直接拖拽Action编辑器中的 ...

  2. 关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox

    太难了QAQ 先看看phar是啥https://blog.csdn.net/u011474028/article/details/54973571 简单的说,phar就是php的压缩文件,它可以把多个 ...

  3. Linux用户配置文件

    一,用户信息文件 /etc/passwd 1,用户管理简介 1,越是对服务器安全性要求高的服务器,越需要建立合理的用户权限等级制度和服务器操作规范 2,在Linux中主要是通过用户配置文件来查看和修改 ...

  4. python-列表list和元组tuple

    list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: >>> ...

  5. 记一次MacPro风扇一直转的问题排查

    1.查看CPU占用最高的进程 借助活动监视器,查看CPU占用最高的进程,可以观察到是Chrome浏览器 2.打开Chrome的任务管理器 2.1.查看CPU占用最高的chrome进程 3.分析和结束进 ...

  6. 【Codeforces 1097F】Alex and a TV Show(bitset & 莫比乌斯反演)

    Description 你需要维护 \(n\) 个可重集,并执行 \(m\) 次操作: 1 x v:\(X\leftarrow \{v\}\): 2 x y z:\(X\leftarrow Y \cu ...

  7. P6100 [USACO19FEB]Painting the Barn G

    本题解提供的做法思路应该是比较清晰的,可惜代码实现比较繁琐,仅供大家参考. 题解 不难发现 \(x\) ,\(y\) 的取值范围只有 \(200\) ,所以我们可以考虑从这里入手.我们可以先通过二维前 ...

  8. Java中CAS原理分析(volatile和synchronized浅析)

    CAS是什么? CAS英文解释是比较和交换,是cpu底层的源语,是解决共享变量原子性实现方案,它定义了三个变量,内存地址值对应V,期待值E和要修改的值U,如下图所示,这些变量都是在高速缓存中的,如果两 ...

  9. SpringBoot瘦身部署(15.9 MB - 92.3 KB)

    1. 简介   SpringBoot项目部署虽然简单,但是经常因为修改了少量代码而需要重新打包上传服务器重新部署,而公网服务器的网速受限,可能整个项目的代码文件仅仅只有1-2MB甚至更少,但是需要上传 ...

  10. JavaSE25-Junit&注解

    1.Junit单元测试 1.1 测试分类 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具体的执行流程. Junit使用:白盒测试 步骤: ...