Browse Source

Merge pull request #201 from maplepie/master

增加邮件发送功能
奇淼(piexlmax 4 years ago
parent
commit
f3ad4838cd

+ 23 - 0
server/api/v1/sys_email.go

@@ -0,0 +1,23 @@
+package v1
+
+import (
+	"fmt"
+	"gin-vue-admin/global/response"
+	"gin-vue-admin/service"
+	"github.com/gin-gonic/gin"
+)
+
+// @Tags system
+// @Summary 发送测试邮件
+// @Security ApiKeyAuth
+// @Produce  application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
+// @Router /email/emailTest [post]
+func EmailTest(c *gin.Context) {
+	err := service.EmailTest()
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("发送失败,%v", err), c)
+	} else {
+		response.OkWithData("发送成功", c)
+	}
+}

+ 11 - 2
server/config.yaml

@@ -11,7 +11,7 @@ jwt:
 # mysql connect configuration
 mysql:
   username: root
-  password: 'Aa@6447985'
+  password: 'root'
   path: '127.0.0.1:3306'
   db-name: 'qmPlus'
   config: 'charset=utf8mb4&parseTime=True&loc=Local'
@@ -80,4 +80,13 @@ zap:
   # LowercaseLevelEncoder:小写, LowercaseColorLevelEncoder:小写带颜色,CapitalLevelEncoder: 大写, CapitalColorLevelEncoder: 大写带颜色,
   encode_level: 'LowercaseColorLevelEncoder'
   stacktrace_key: 'stacktrace'
-  log_in_console: true
+  log_in_console: true
+
+email:
+  email_from: '[email protected]'
+  email_nick_name: 'test'
+  email_secret: 'xxx'
+  email_to: '[email protected]'
+  email_host: 'smtp.163.com'
+  email_port: 465
+  email_isSSL: true

+ 11 - 0
server/config/config.go

@@ -11,6 +11,7 @@ type Server struct {
 	Captcha     Captcha     `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
 	Zap         Zap         `mapstructure:"zap" json:"zap" yaml:"zap"`
 	LocalUpload LocalUpload `mapstructure:"localUpload" json:"localUpload" yaml:"localUpload"`
+	Email       Email       `mapstructure:"email" json:"email" yaml:"email"`
 }
 
 type System struct {
@@ -84,3 +85,13 @@ type Zap struct {
 	StacktraceKey string `mapstructure:"stacktrace_key" json:"stacktraceKey" yaml:"stacktrace_key"`
 	LogInConsole  bool   `mapstructure:"log_in_console" json:"logInConsole" yaml:"log_in_console"`
 }
+
+type Email struct {
+	EmailFrom         string `mapstructure:"email_from" json:"emailFrom" yaml:"email_from"`
+	EmailNickName         string `mapstructure:"email_nick_name" json:"emailNickName" yaml:"email_nick_name"`
+	EmailSecret         string `mapstructure:"email_secret" json:"emailSecret" yaml:"email_secret"`
+	EmailTo         string `mapstructure:"email_to" json:"emailTo" yaml:"email_to"`
+	EmailHost         string `mapstructure:"email_host" json:"emailHost" yaml:"email_host"`
+	EmailPort         int `mapstructure:"email_port" json:"emailPort" yaml:"email_port"`
+	EmailIsSSL         bool `mapstructure:"email_isSSL" json:"emailIsSSL" yaml:"email_isSSL"`
+}

+ 1 - 0
server/go.mod

@@ -19,6 +19,7 @@ require (
 	github.com/go-sql-driver/mysql v1.5.0
 	github.com/golang/protobuf v1.4.2 // indirect
 	github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
+	github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
 	github.com/json-iterator/go v1.1.10 // indirect
 	github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible
 	github.com/lestrrat-go/strftime v1.0.3 // indirect

+ 1 - 0
server/initialize/router.go

@@ -43,6 +43,7 @@ func Routers() *gin.Engine {
 	router.InitSysDictionaryDetailRouter(ApiGroup)   // 字典详情管理
 	router.InitSysDictionaryRouter(ApiGroup)         // 字典管理
 	router.InitSysOperationRecordRouter(ApiGroup)    // 操作记录
+	router.InitEmailRouter(ApiGroup)                 // 邮件相关路由
 
 	global.GVA_LOG.Info("router register success")
 	return Router

+ 14 - 0
server/router/sys_email.go

@@ -0,0 +1,14 @@
+package router
+
+import (
+	"gin-vue-admin/api/v1"
+	"gin-vue-admin/middleware"
+	"github.com/gin-gonic/gin"
+)
+
+func InitEmailRouter(Router *gin.RouterGroup) {
+	UserRouter := Router.Group("email").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	{
+		UserRouter.POST("emailTest", v1.EmailTest) // 发送测试邮件
+	}
+}

+ 17 - 0
server/service/sys_email.go

@@ -0,0 +1,17 @@
+package service
+
+import (
+	"gin-vue-admin/utils"
+)
+
+// @title    EmailTest
+// @description   发送邮件测试
+// @auth                    (2020/09/08  13:58
+// @return    err            error
+
+func EmailTest() (err error) {
+	subject := "test"
+	body := "test"
+	err = utils.EmailTest(subject, body)
+	return err
+}

+ 50 - 0
server/utils/email.go

@@ -0,0 +1,50 @@
+package utils
+
+import (
+	"fmt"
+	"strings"
+	"net/smtp"
+	"crypto/tls"
+
+	"gin-vue-admin/global"
+
+	"github.com/jordan-wright/email"
+)
+
+func Email(subject string, body string) error {
+	to := strings.Split(global.GVA_CONFIG.Email.EmailTo, ",")
+	return send(to, subject, body)
+}
+
+func EmailTest(subject string, body string) error {
+	to := []string{global.GVA_CONFIG.Email.EmailFrom}
+	return send(to, subject, body)
+}
+
+func send(to []string, subject string, body string) error {
+	from := global.GVA_CONFIG.Email.EmailFrom
+	nickName := global.GVA_CONFIG.Email.EmailNickName
+	secret := global.GVA_CONFIG.Email.EmailSecret
+	host := global.GVA_CONFIG.Email.EmailHost
+	port := global.GVA_CONFIG.Email.EmailPort
+	isSSL := global.GVA_CONFIG.Email.EmailIsSSL
+
+	auth := smtp.PlainAuth("", from, secret, host)
+	e := email.NewEmail()
+	if nickName == "" {
+		e.From = fmt.Sprintf("%s <%s>", nickName, from)
+	}else{
+		e.From = from
+	}
+	e.To = to
+	e.Subject = subject
+	e.HTML = []byte(body)
+	var err error
+	hostAddr := fmt.Sprintf("%s:%d", host, port)
+	if isSSL {
+		err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host})
+	}else{
+		err = e.Send(hostAddr, auth)
+	}
+	return err
+}

+ 15 - 0
web/src/api/email.js

@@ -0,0 +1,15 @@
+import service from '@/utils/request'
+
+// @Tags email
+// @Summary 发送测试邮件
+// @Security ApiKeyAuth
+// @Produce  application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
+// @Router /email/emailTest [post]
+export const emailTest = (data) => {
+    return service({
+        url: "/email/emailTest",
+        method: 'post',
+        data
+    })
+}

+ 43 - 1
web/src/view/systemTools/system/system.vue

@@ -105,6 +105,31 @@
 			<el-form-item label="logFile">
 				<el-checkbox v-model="config.log.logFile"></el-checkbox>
 			</el-form-item>
+			<h2>邮箱配置</h2>
+			<el-form-item label="emailFrom">
+				<el-input v-model="config.email.emailFrom"></el-input>
+			</el-form-item>
+			<el-form-item label="emailNickName">
+				<el-input v-model="config.email.emailNickName"></el-input>
+			</el-form-item>
+			<el-form-item label="emailSecret">
+				<el-input v-model="config.email.emailSecret"></el-input>
+			</el-form-item>
+			<el-form-item label="emailTo">
+				<el-input v-model="config.email.emailTo" placeholder="可多个,以逗号分隔"></el-input>
+			</el-form-item>
+			<el-form-item label="emailHost">
+				<el-input v-model="config.email.emailHost"></el-input>
+			</el-form-item>
+			<el-form-item label="emailPort">
+				<el-input v-model.number="config.email.emailPort"></el-input>
+			</el-form-item>
+			<el-form-item label="emailIsSSL">
+				<el-checkbox v-model="config.email.emailIsSSL"></el-checkbox>
+			</el-form-item>
+			<el-form-item label="测试邮件">
+				<el-button @click="email">测试邮件</el-button>
+			</el-form-item>
 			<el-form-item>
 				<el-button @click="update" type="primary">立即更新</el-button>
 				<el-button @click="reload" type="primary">重启服务(开发中)</el-button>
@@ -115,6 +140,7 @@
 
 <script>
 import { getSystemConfig, setSystemConfig } from "@/api/system";
+import { emailTest } from "@/api/email";
 export default {
   name: "Config",
   data() {
@@ -129,7 +155,8 @@ export default {
         qiniu: {},
         captcha: {},
 		log: {},
-		localUpload: {}
+		localUpload: {},
+		email: {},
       }
     };
   },
@@ -153,6 +180,21 @@ export default {
         });
         await this.initForm();
       }
+    },
+    async email() {
+      const res = await emailTest();
+      if (res.code == 0) {
+        this.$message({
+          type: "success",
+          message: "邮件发送成功"
+        });
+        await this.initForm();
+      } else {
+		this.$message({
+          type: "error",
+          message: "邮件发送失败"
+        });
+	  }
     }
   }
 };