Skip to content

Commit

Permalink
1. 优化界面显示
Browse files Browse the repository at this point in the history
2. 增加主题变量,支持单个发件箱自定义内容
  • Loading branch information
uyoufu committed Sep 2, 2021
1 parent dbc58b2 commit a1bf950
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 73 deletions.
Binary file added README.assets/image-20210901235949132.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20210902000549245.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20210902000857298.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20210902000905449.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README.assets/image-20210902075728011.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
191 changes: 125 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## 简介

本程序名为“邮件群发助手”,旨在将邮件的发送自动化,批量化和可定制化。最简单的应用场景就是财务可以利用它向员工发送其相应的工资条。
![](https://i.loli.net/2021/09/02/3FZ9QBYqcfrtuV1.png)

本程序名为“邮件群发助手”,旨在实现邮件发送自动化,批量化和内容可定制化。最简单的应用场景就是财务可以利用它向员工发送每个人对应的工资条。

## 特点

Expand All @@ -18,154 +20,211 @@

每个发件人采用单独的线程进行发送,所以一个线程挂掉之后并不会使发件进程停止,会由其它发件的所在线程继续发件。

- 支持发送内容模板可自定义
- 支持重发

如果仅有一个发件箱,当发件失败后,会在其它邮件发送完成后,再次发送,可重发次数最大为5次。当有多个发件箱时,若 A 发件箱发件失败后,会转由 B 发件箱进行发送

- 支持邮件内容模板自定义

模板完全可自定义,可根据需要定义自己所需的模板,并保存到模板库,以供今后重复使用。

模板采用 html 格式定义。

- 支持无限变量,使得模板高度自由
- 支持无限变量,使得模板内容根据数据自动变化

可以在模板中引入变量,在发送的过程中,会自动将变量值替换成其真实的值进行发送,可以实现同一套模板,不同的收件人,接收的具体内容不同。

- 支持失败重发

所有的发送过程都有记录,对于未发送成功的邮件,可以在发送任务完成后,点击“重复发送”按钮进行重发
所有的发送过程都有记录,对于未发送成功的邮件,可以在发送任务完成后,手动进行重发

重发过程支持多线程。

## 使用环境要求

1. windows
1. windows 7 及以上

2. .NET Framework 4.6.2 或者以上,下载地址:https://dotnet.microsoft.com/download/dotnet-framework
3. 安装 Edge 浏览器,且版本不低于 Edge dev 87.0.654.0,下载地址:https://www.microsoftedgeinsider.com/zh-cn/download
2. .NET Framework 4.6.2 及以上,下载地址:https://dotnet.microsoft.com/download/dotnet-framework
3. webview2环境,下载地址:https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/

## 功能介绍
## 如何使用

### 登陆界面
**编译版本:**

1. 下载程序,解压到自定义目录;
2. 单击 `邮件批量发送.exe` 运行。

**手动编译:**

1. 克隆仓库,切换到 `master` 分支;
2. 通过终端进入到 `UI` 目录,在此处运行 `npm install` 安装依赖包,然后执行 `npm run build:prod` 进行编译;
3. 打开 `Server`,用 `visual studio 2019` 或更高版本打开 `Server.sln`,打开后编为 `release;`
4. 将第 3 步编译的 `dist` 文件夹内所有文件夹及文件拷贝到 `release``public` 目录中(如果没有,请新建);
5. 至此,编译完成。单击 release 中的 `邮件批量发送.exe` 即可运行。

> 注意,上述两种方法都需要 `webview2` 运行环境的支持,请提前自行安装。
## 发件步骤

![image-20201003190048168](https://i.loli.net/2020/10/03/VQh4vLG5FaxZUEP.png)
1. 添加发件箱(已添加请忽略)
2. 添加收件箱(已添加请忽略)
3. 导入所需模板(已添加请忽略)
4. 打开【新建发件】,输入主题 --> 选择收件人 --> 选择模板 --> 选择数据 -->预览确认发件数量和模板正确性 --> 退出预览 -->点击【发送】
5. 如果提示发送失败,转到【发件历史】,进行重发

第一次使用时,需要进行注册。
## 功能介绍

### 登陆界面

注册流程:
![image-20210901235949132](https://i.loli.net/2021/09/01/aIc3Jsm41DK9Mdj.png)

- 先输入用户名
- 然后输入密码
- 点击注册
如果系统中不存在账号名称,则系统会自动新建账号。

> 特别注意:
>
> 注册的信息是保存在本地的数据库中。
>
> 每个用户的数据是隔离的,不能相互访问
### 个人中心
### 首页

![](https://i.loli.net/2021/09/02/3FZ9QBYqcfrtuV1.png)

首页为欢迎页面。在首页中,会加载左下角的 Live2d 模块,如果不需要,可以手动关闭。

![](C:\Users\galens\Desktop\ZXMVRPlD1K3eqg8.png)
### 系统设置

个人中心主要是对账户内发件信息的统计、发件箱种类及数量图、收件箱种类及数量图和个人信息中心。个人信息中心包括注销账户和退出两个功能。
![](https://i.loli.net/2021/09/02/mGNdJertsIbBFQc.png)

### 发送设置
- 发件间隔范围

![image-20201003194833558](https://i.loli.net/2020/10/03/isWu9xpL2gKly7G.png)
为了避免因频繁发送邮件而导致被服务器认为是垃圾邮箱,所以,发送两封邮件之间需要有一定的时间间隔,为了使得发送时间间隔具有不规律性,用间隔范围来进行控制

在发送设置中,设置发送间隔和间隔的波动。
实际发件间隔值 =最小值 + (0,1)之间的随机数*(最大值-最小值)

为了避免因频繁发送邮件而导致被服务器认为是垃圾邮箱,所以,发送两封邮件之间需要有一定的时间间隔,为了使得发送时间间隔具有不规律性,用间隔波动来进行控制。
- 自动重发

实际波动值 = (0,1)之间的随机数*间隔波动值
勾选后,在发送中,会对失败的邮件重新发送,当重发次数超过 5 次,则会退出重发。对于重发失败的,可以在【发件历史】中重新发送。

### 发件人
### 邮箱管理

![image-20201003195209727](https://i.loli.net/2020/10/03/gIZUeqrJEyz1Gbu.png)
#### 发件人

在此处添加发件人。可以单个添加,也可以批量从 Excel 中添加。
![](https://i.loli.net/2021/09/02/UEqygPt4r7vHZfF.png)

在使用批量添加发件人功能时,Excel 表中第一行为表头,必须含有 “姓名”、“邮箱”、“SMTP”、“密码” 这些表头,可以参考模板中的 “发件人”Sheet 来规范格式。
此处用于管理发件人信息。下面列出在使用中需要注意的功能进行说明:

是否作为发件人功能:是否利用该发件人发送邮件,如果关掉,那么在本次发件过程中,将不会用它进行发件。
**组管理:**

![](https://i.loli.net/2021/09/02/yk4sDP3BATedCn5.png)

界面内左侧为分组区域,在此区域右键可以弹出上下文菜单,其功能分别为【添加组】、【添加子组】、【修改】和【删除】。其作用如其名,不多赘述。

**从EXCEL导入:**

批量从 Excel 中导入发件箱。在使用批量添加发件人功能时,Excel 表中第一行为表头,必须含有 `userName``email``smtp``password` 这些表头,可以参考 Excel 模板中的 “发件人” Sheet 来规范格式。

> 特别注意
>
> 发件采用的 SMTP 服务器,所以,它的密码并不是邮箱的密码,而是登陆邮箱后,自己申请的 SMTP 密码。
>
> 比如,163邮箱 SMTP 密码获取方式如下:https://www.yisu.com/zixun/97973.html
### 收件人
#### 收件人

![](https://i.loli.net/2021/09/02/PzjDUuBHa8Y1rnJ.png)

![image-20201003200320214](https://i.loli.net/2020/10/03/ZTFbr18HBa6APYs.png)
该模块主要用于对收件箱的分组和管理,使用方式、注意要点与发件人一致。

收件人支持单个添加和从 Excel 批量添加
收件箱只需要姓名和邮箱。

在使用从 Excel批量添加 时,第一行为表头,其中,表头必须含有这些名称:“姓名”和"邮箱",具体格式可以参考模板中的 “收件人” Sheet 来规范格式。
#### 正文模板

### 导入数据
![](https://i.loli.net/2021/09/02/k37Cm4cyNvxbPD8.png)

![image-20201003200656769](https://i.loli.net/2020/10/03/Fp37YUO4iKXWnfz.png)
在【正文模板】模块中可以对模板进行定义,它的格式是 html 格式。先在外面用 html 定义好模板,然后通过上述中的【导入模板】功能将定义的模板导入到系统。

导入的数据将表头作为变量,其值作为变量的值,在发送的过程中,如果模板中有相应名称的变量,就用变量的值对变量进行替换,然后再发送
在模板的编写过程中,可以使用 `{{}}` 来标记为变量,在发件的过程中,程序会在数据中查找该变量,如果查找到,就会使用实际的数据将变量替换掉

所以,为了建立对应关系,每一条数据需要有“姓名”列,这样才能和收件箱中的姓名进行对应
变量定义的格式是为:`{{变量名}}`

导入数据只支持从 Excel 批量导入。
### 发件管理

### 模板
#### 新建发件

![image-20201003201226050](https://i.loli.net/2020/10/03/L6by1AqljoOYQha.png)
![](https://i.loli.net/2021/09/02/HcKWsiX4N9MeOnt.png)

在模板模块中可以对模板进行定义,它的格式是 html 格式,如果熟悉 html 的话,也可以自己编辑 html 文件,放到全局模板路径 `Template` 或者用户模板路径 `UserData\用户名\Data\Template` 位置
此处进行邮件的发送

变量名称就是导入数据中的表头名称。在使用的时候,格式是为:`{{变量名}}`
当前录入了发件人、收件人和模板后,即可开始发件

### 发送
**主题:**

![image-20201003201755056](https://i.loli.net/2020/10/03/RpFB7mjwOohWtdG.png)
发件的主题是必须的,主有两个作用:一是为邮件的主题,二是同一次发件将会归到一个发件历史记录中,该主题为历史记录组的名称。

在这个地方进行邮件的发送
主题也支持变量声明,比如:`{{日期}}-工资明细``日期`即为定义的变量,在发送邮件时,它将被替换成 Excel 表中的实际数据

前面已经选择了发件人,收件人,模板和导入了模板中的数据,发送模块将会利用这些数据开始发送邮件。主要步骤有4个:
**收件人**

- 新建
- 邮件预览
- 正式发送及显示发送情况
- 浏览发送结果
![abc](https://i.loli.net/2021/09/02/zZRCqr459ylHt3g.pn)

右下角的箭头可以跳转到上一次发送的结果页面,方便查看
收件人选择框如上图,在选择收件人的时候,可以选择收件组,也可以选择组中的收件人。在选择的过程中,不需要担心收件人重复问题,系统会在后台自动去重。选择完成后,点击白色窗体空白部分即可确认和退出选择

## 如何使用?
**模板:**

1. 注册账户
2. 登陆账户
3. 添加发件人
4. 添加收件人
5. 导入与收件人对应的变量数据
6. 选择模板
7. 开始发送
1. 新建
2. 输入标题,预览,如果有必要,可以查看每一条邮件是否正确
3. 开始发送
4. 查看发送结果,如果未成功,可以重复发送
此处的模板即为邮件的正文内容,选择我们需要的模板即可。

在发件中,可以针对每个收件人设置单独的模板,需要在数据表中增加 `template` 列,并填入所需的模板名称。

除了自定义模板外,也可以直接针对每个收件人自定义内容,需要在数据表中增加 `body` 列,并填入发送的主体内容。

自定义内容的优先级高于自定义模板。

> 对单个收件人的自定义模板和自定义内容均支持变量声明。
**数据:**

选择模板后,还需要选择对应的数据。此处数据中的表头要与模板中定义的变量有对应关系,且数据中必须包含 `useName` 列,用于与发件箱匹配。

> **注意:**
>
> 在发件之前,请点击预览,复核发件的数量是否正确,模板数据是否按预想修改。如果发件数量或者数据不正确,请复核 excel 数据是否正确。
**预览:**

![](https://i.loli.net/2021/09/02/nQGt3Deh2CrO7Xu.png)

#### 发件历史

![](https://i.loli.net/2021/09/02/EGNnkcAXY4PrKIQ.png)

发件历史显示历次所发的所有邮件记录,一次发送记录为一条历史。单击详细可以查看该次历史下所有的发件。如果有发件失败的,可以点【重发】进行发送,只会重发失败的邮件。

## 反馈与建议

如果你在使用中发现了 bug, 或者对该软件有任何建议,都欢迎联系我,让我们将这款软件一起变得更优秀吧!

联系方式:

微信:gmx260827400

QQ:260827400

QQ群:877458612

邮箱:[email protected]

GitHub:https://github.com/GalensGan/SendMultipleEmails

个人主页:galensgan.github.io
个人主页:https://galensgan.github.io

## 支持与赞赏

如果你觉得本软件帮助到你了,欢迎赞赏支持,你的支持,将是我继续优化的动力!

![8cee0aef69c70889092500d509df5b8](https://i.loli.net/2020/10/05/tg3HAo4R8L5OilP.jpg)
**支付宝:**

![](https://i.loli.net/2021/08/13/U2s7gKn1zRw3uP4.png)

**微信:**

![](https://i.loli.net/2021/08/13/JOw9cxomhBAZFW8.png)

Binary file modified Server/.vs/Server/v16/.suo
Binary file not shown.
4 changes: 3 additions & 1 deletion Server/Server/Database/Models/SendItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ public class SendItem:AutoObjectId
public string receiverName { get; set; }
public string receiverEmail { get; set; }

// 邮件内容
// 邮件主题
public string subject { get; set; }

// 邮件 html 内容
public string html { get; set; }

// 进度信息
Expand Down
2 changes: 1 addition & 1 deletion Server/Server/Http/Controller/Ctrler_Group.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public void GetEmails(string id)

// 删除单个邮箱
[Route(HttpVerbs.Delete, "/emails/{id}")]
public void DeleteEmail(int id)
public void DeleteEmail(string id)
{
// 获取所有待更新的key
LiteDb.Delete<SendBox>(id);
Expand Down
34 changes: 31 additions & 3 deletions Server/Server/Http/Modules/SendEmail/SendTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,50 @@ private SendTask(string userId, string subject, JArray receivers, JArray data, s

var item = new SendItem()
{
subject = _subject,
receiverName = re.userName,
receiverEmail = re.email,
};

// 获取数据
List<string> keys = (itemData as JObject).Properties().ToList().ConvertAll(p => p.Name);
// 对所有数据进行替换
string sendHtml = _template.html;
// 判断是否有自定义内容,然后判断是否有自定义模板
if (keys.Contains("body"))
{
// 获取 body 值
string body = itemData.Value<string>("body");
if (!string.IsNullOrEmpty(body))
{
sendHtml = body;
}
}
else if (keys.Contains("template"))
{
string customTemplateName = itemData.Value<string>("template");
if (!string.IsNullOrEmpty(customTemplateName))
{
// 获取新模板,如果失败,则跳过,不发送
var customTemplate = _liteDb.SingleOrDefault<Template>(t => t.name == customTemplateName);
if (customTemplate != null)
{
sendHtml = customTemplate.html;
}
}
}

// 替换模板内数据
string subjectTemp = _subject;
foreach (string key in keys)
{
var regex = new Regex("{{\\s*" + key + "\\s*}}");
sendHtml = regex.Replace(sendHtml, itemData[key].Value<string>());

// 同时替换主题数据
subjectTemp = regex.Replace(subjectTemp, itemData[key].Value<string>());
}

item.html = sendHtml;
item.subject = subjectTemp;

// 添加到保存的集合中
_sendItems.Add(item);
Expand Down Expand Up @@ -412,7 +440,7 @@ private void SendItems(List<SendItem> sendItemList, string historyId)
};
SendingInfo = sendingInfo;
}
else if(setting.isAutoResend) // 重新发送时,才重新推入栈中
else if (setting.isAutoResend) // 重新发送时,才重新推入栈中
{
// 重新推入栈中
sendItems.Push(sendItem);
Expand Down
2 changes: 1 addition & 1 deletion Server/Server/Pages/ShellView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Server.Pages"
mc:Ignorable="d"
Title="Stylet Start Project" Height="600" Width="1200"
Title="邮件批量发送系统" Height="600" Width="1200"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:webview2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
d:DataContext="{d:DesignInstance local:ShellViewModel}">
Expand Down
Binary file added Server/Server/SendMultipleEmail.ico
Binary file not shown.
Loading

0 comments on commit a1bf950

Please sign in to comment.