Skip to content

Commit fd0f741

Browse files
author
奇淼(piexlmax
authored
Merge pull request #201 from maplepie/master
增加邮件发送功能
2 parents be9c85a + 6631aa3 commit fd0f741

File tree

10 files changed

+186
-3
lines changed

10 files changed

+186
-3
lines changed

server/api/v1/sys_email.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package v1
2+
3+
import (
4+
"fmt"
5+
"gin-vue-admin/global/response"
6+
"gin-vue-admin/service"
7+
"github.com/gin-gonic/gin"
8+
)
9+
10+
// @Tags system
11+
// @Summary 发送测试邮件
12+
// @Security ApiKeyAuth
13+
// @Produce application/json
14+
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
15+
// @Router /email/emailTest [post]
16+
func EmailTest(c *gin.Context) {
17+
err := service.EmailTest()
18+
if err != nil {
19+
response.FailWithMessage(fmt.Sprintf("发送失败,%v", err), c)
20+
} else {
21+
response.OkWithData("发送成功", c)
22+
}
23+
}

server/config.yaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jwt:
1111
# mysql connect configuration
1212
mysql:
1313
username: root
14-
password: 'Aa@6447985'
14+
password: 'root'
1515
path: '127.0.0.1:3306'
1616
db-name: 'qmPlus'
1717
config: 'charset=utf8mb4&parseTime=True&loc=Local'
@@ -80,4 +80,13 @@ zap:
8080
# LowercaseLevelEncoder:小写, LowercaseColorLevelEncoder:小写带颜色,CapitalLevelEncoder: 大写, CapitalColorLevelEncoder: 大写带颜色,
8181
encode_level: 'LowercaseColorLevelEncoder'
8282
stacktrace_key: 'stacktrace'
83-
log_in_console: true
83+
log_in_console: true
84+
85+
email:
86+
email_from: '[email protected]'
87+
email_nick_name: 'test'
88+
email_secret: 'xxx'
89+
email_to: '[email protected]'
90+
email_host: 'smtp.163.com'
91+
email_port: 465
92+
email_isSSL: true

server/config/config.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type Server struct {
1111
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
1212
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
1313
LocalUpload LocalUpload `mapstructure:"localUpload" json:"localUpload" yaml:"localUpload"`
14+
Email Email `mapstructure:"email" json:"email" yaml:"email"`
1415
}
1516

1617
type System struct {
@@ -84,3 +85,13 @@ type Zap struct {
8485
StacktraceKey string `mapstructure:"stacktrace_key" json:"stacktraceKey" yaml:"stacktrace_key"`
8586
LogInConsole bool `mapstructure:"log_in_console" json:"logInConsole" yaml:"log_in_console"`
8687
}
88+
89+
type Email struct {
90+
EmailFrom string `mapstructure:"email_from" json:"emailFrom" yaml:"email_from"`
91+
EmailNickName string `mapstructure:"email_nick_name" json:"emailNickName" yaml:"email_nick_name"`
92+
EmailSecret string `mapstructure:"email_secret" json:"emailSecret" yaml:"email_secret"`
93+
EmailTo string `mapstructure:"email_to" json:"emailTo" yaml:"email_to"`
94+
EmailHost string `mapstructure:"email_host" json:"emailHost" yaml:"email_host"`
95+
EmailPort int `mapstructure:"email_port" json:"emailPort" yaml:"email_port"`
96+
EmailIsSSL bool `mapstructure:"email_isSSL" json:"emailIsSSL" yaml:"email_isSSL"`
97+
}

server/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
github.com/go-sql-driver/mysql v1.5.0
2020
github.com/golang/protobuf v1.4.2 // indirect
2121
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
22+
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
2223
github.com/json-iterator/go v1.1.10 // indirect
2324
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible
2425
github.com/lestrrat-go/strftime v1.0.3 // indirect

server/initialize/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func Routers() *gin.Engine {
4343
router.InitSysDictionaryDetailRouter(ApiGroup) // 字典详情管理
4444
router.InitSysDictionaryRouter(ApiGroup) // 字典管理
4545
router.InitSysOperationRecordRouter(ApiGroup) // 操作记录
46+
router.InitEmailRouter(ApiGroup) // 邮件相关路由
4647

4748
global.GVA_LOG.Info("router register success")
4849
return Router

server/router/sys_email.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package router
2+
3+
import (
4+
"gin-vue-admin/api/v1"
5+
"gin-vue-admin/middleware"
6+
"github.com/gin-gonic/gin"
7+
)
8+
9+
func InitEmailRouter(Router *gin.RouterGroup) {
10+
UserRouter := Router.Group("email").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
11+
{
12+
UserRouter.POST("emailTest", v1.EmailTest) // 发送测试邮件
13+
}
14+
}

server/service/sys_email.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package service
2+
3+
import (
4+
"gin-vue-admin/utils"
5+
)
6+
7+
// @title EmailTest
8+
// @description 发送邮件测试
9+
// @auth (2020/09/08 13:58
10+
// @return err error
11+
12+
func EmailTest() (err error) {
13+
subject := "test"
14+
body := "test"
15+
err = utils.EmailTest(subject, body)
16+
return err
17+
}

server/utils/email.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"net/smtp"
7+
"crypto/tls"
8+
9+
"gin-vue-admin/global"
10+
11+
"github.com/jordan-wright/email"
12+
)
13+
14+
func Email(subject string, body string) error {
15+
to := strings.Split(global.GVA_CONFIG.Email.EmailTo, ",")
16+
return send(to, subject, body)
17+
}
18+
19+
func EmailTest(subject string, body string) error {
20+
to := []string{global.GVA_CONFIG.Email.EmailFrom}
21+
return send(to, subject, body)
22+
}
23+
24+
func send(to []string, subject string, body string) error {
25+
from := global.GVA_CONFIG.Email.EmailFrom
26+
nickName := global.GVA_CONFIG.Email.EmailNickName
27+
secret := global.GVA_CONFIG.Email.EmailSecret
28+
host := global.GVA_CONFIG.Email.EmailHost
29+
port := global.GVA_CONFIG.Email.EmailPort
30+
isSSL := global.GVA_CONFIG.Email.EmailIsSSL
31+
32+
auth := smtp.PlainAuth("", from, secret, host)
33+
e := email.NewEmail()
34+
if nickName == "" {
35+
e.From = fmt.Sprintf("%s <%s>", nickName, from)
36+
}else{
37+
e.From = from
38+
}
39+
e.To = to
40+
e.Subject = subject
41+
e.HTML = []byte(body)
42+
var err error
43+
hostAddr := fmt.Sprintf("%s:%d", host, port)
44+
if isSSL {
45+
err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host})
46+
}else{
47+
err = e.Send(hostAddr, auth)
48+
}
49+
return err
50+
}

web/src/api/email.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import service from '@/utils/request'
2+
3+
// @Tags email
4+
// @Summary 发送测试邮件
5+
// @Security ApiKeyAuth
6+
// @Produce application/json
7+
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
8+
// @Router /email/emailTest [post]
9+
export const emailTest = (data) => {
10+
return service({
11+
url: "/email/emailTest",
12+
method: 'post',
13+
data
14+
})
15+
}

web/src/view/systemTools/system/system.vue

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,31 @@
105105
<el-form-item label="logFile">
106106
<el-checkbox v-model="config.log.logFile"></el-checkbox>
107107
</el-form-item>
108+
<h2>邮箱配置</h2>
109+
<el-form-item label="emailFrom">
110+
<el-input v-model="config.email.emailFrom"></el-input>
111+
</el-form-item>
112+
<el-form-item label="emailNickName">
113+
<el-input v-model="config.email.emailNickName"></el-input>
114+
</el-form-item>
115+
<el-form-item label="emailSecret">
116+
<el-input v-model="config.email.emailSecret"></el-input>
117+
</el-form-item>
118+
<el-form-item label="emailTo">
119+
<el-input v-model="config.email.emailTo" placeholder="可多个,以逗号分隔"></el-input>
120+
</el-form-item>
121+
<el-form-item label="emailHost">
122+
<el-input v-model="config.email.emailHost"></el-input>
123+
</el-form-item>
124+
<el-form-item label="emailPort">
125+
<el-input v-model.number="config.email.emailPort"></el-input>
126+
</el-form-item>
127+
<el-form-item label="emailIsSSL">
128+
<el-checkbox v-model="config.email.emailIsSSL"></el-checkbox>
129+
</el-form-item>
130+
<el-form-item label="测试邮件">
131+
<el-button @click="email">测试邮件</el-button>
132+
</el-form-item>
108133
<el-form-item>
109134
<el-button @click="update" type="primary">立即更新</el-button>
110135
<el-button @click="reload" type="primary">重启服务(开发中)</el-button>
@@ -115,6 +140,7 @@
115140

116141
<script>
117142
import { getSystemConfig, setSystemConfig } from "@/api/system";
143+
import { emailTest } from "@/api/email";
118144
export default {
119145
name: "Config",
120146
data() {
@@ -129,7 +155,8 @@ export default {
129155
qiniu: {},
130156
captcha: {},
131157
log: {},
132-
localUpload: {}
158+
localUpload: {},
159+
email: {},
133160
}
134161
};
135162
},
@@ -153,6 +180,21 @@ export default {
153180
});
154181
await this.initForm();
155182
}
183+
},
184+
async email() {
185+
const res = await emailTest();
186+
if (res.code == 0) {
187+
this.$message({
188+
type: "success",
189+
message: "邮件发送成功"
190+
});
191+
await this.initForm();
192+
} else {
193+
this.$message({
194+
type: "error",
195+
message: "邮件发送失败"
196+
});
197+
}
156198
}
157199
}
158200
};

0 commit comments

Comments
 (0)