发送邮件

dev
truthhun 1 year ago
parent 22f3b2b417
commit de48daca20

@ -44,11 +44,30 @@ func (s *ConfigAPIService) UpdateConfig(ctx context.Context, req *pb.Configs) (*
fmt.Println(err.Error())
}
isEmail := false
for idx, cfg := range cfgs {
if cfg.Category == model.ConfigCategoryEmail && cfg.Name == model.ConfigEmailPassword && cfg.Value == "******" {
// 6个星号不修改密码
cfgs[idx].Value = s.dbModel.GetConfigOfEmail(model.ConfigEmailPassword).Password
}
isEmail = isEmail || cfg.Category == model.ConfigCategoryEmail
}
err = s.dbModel.UpdateConfigs(cfgs, "value")
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
if isEmail {
cfgEmail := s.dbModel.GetConfigOfEmail(model.ConfigEmailEnable, model.ConfigEmailTestEmail)
if cfgEmail.Enable && cfgEmail.TestEmail != "" {
err = s.dbModel.SendMail("测试邮件", cfgEmail.TestEmail, "这是一封测试邮件")
if err != nil {
return nil, status.Error(codes.Internal, "邮件发送失败:"+err.Error())
}
}
}
return &emptypb.Empty{}, nil
}
@ -73,6 +92,12 @@ func (s *ConfigAPIService) ListConfig(ctx context.Context, req *pb.ListConfigReq
var pbConfigs []*pb.Config
util.CopyStruct(&configs, &pbConfigs)
for idx, cfg := range pbConfigs {
if cfg.Category == model.ConfigCategoryEmail && cfg.Name == model.ConfigEmailPassword {
pbConfigs[idx].Value = "******"
}
}
return &pb.Configs{Config: pbConfigs}, nil
}

@ -31,6 +31,8 @@ require (
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
)
require (

@ -875,6 +875,8 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -883,6 +885,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

@ -1,6 +1,8 @@
package model
import (
"crypto/tls"
"errors"
"moredoc/util/captcha"
"strconv"
"strings"
@ -8,6 +10,7 @@ import (
jsoniter "github.com/json-iterator/go"
"go.uber.org/zap"
"gopkg.in/gomail.v2"
"gorm.io/gorm"
)
@ -275,6 +278,32 @@ type ConfigConverter struct {
// GZIP和svgo都开启转换效率会有所下降可以综合节省约85%的存储空间
}
const (
ConfigEmailEnable = "enable" // 是否启用邮件服务
ConfigEmailHost = "host" // SMTP 服务器地址
ConfigEmailPort = "port" // SMTP 服务器端口
ConfigEmailIsTLS = "is_tls" // 是否启用TLS
ConfigEmailFromName = "from_name"
ConfigEmailUsername = "username" // SMTP 用户名
ConfigEmailPassword = "password" // SMTP 密码
ConfigEmailDuration = "duration" // 验证码有效期,单位为分钟
ConfigEmailTestEmail = "test_email"
ConfigEmailReplyTo = "reply_to"
)
type ConfigEmail struct {
Enable bool `json:"enable"` // 是否启用邮件服务
Host string `json:"host"` // SMTP 服务器地址
Port int `json:"port"` // SMTP 服务器端口
IsTLS bool `json:"is_tls"` // 是否启用TLS
FromName string `json:"from_name"`
Username string `json:"username"`
Password string `json:"password"`
Duration int `json:"duration"` // 验证码有效期,单位为分钟
TestEmail string `json:"test_email"`
// ReplyTo string `json:"reply_to"`
}
const (
ConfigFooterAbout = "about" // 关于我们
ConfigFooterContact = "contact" // 联系我们
@ -502,6 +531,35 @@ func (m *DBModel) GetConfigOfConverter() (config ConfigConverter) {
return
}
func (m *DBModel) GetConfigOfEmail(name ...string) (config ConfigEmail) {
var configs []Config
db := m.db.Where("category = ?", ConfigCategoryEmail)
if len(name) > 0 {
db = db.Where("name in (?)", name)
}
err := db.Find(&configs).Error
if err != nil && err != gorm.ErrRecordNotFound {
m.logger.Error("GetConfigOfEmail", zap.Error(err))
}
var data = make(map[string]interface{})
for _, cfg := range configs {
switch cfg.Name {
case ConfigEmailEnable, ConfigEmailIsTLS:
data[cfg.Name], _ = strconv.ParseBool(cfg.Value)
case ConfigEmailPort, ConfigEmailDuration:
data[cfg.Name], _ = strconv.Atoi(cfg.Value)
default:
data[cfg.Name] = cfg.Value
}
}
bytes, _ := json.Marshal(data)
json.Unmarshal(bytes, &config)
m.logger.Debug("GetConfigOfEmail", zap.Any("data", data), zap.Any("config", config))
return
}
func (m *DBModel) GetConfigOfScore(name ...string) (config ConfigScore) {
var configs []Config
db := m.db.Where("category = ?", ConfigCategoryScore)
@ -525,6 +583,32 @@ func (m *DBModel) GetConfigOfScore(name ...string) (config ConfigScore) {
return
}
func (m *DBModel) SendMail(subject, email string, body string) error {
cfg := m.GetConfigOfEmail()
m.logger.Debug("SendMail", zap.Any("cfg", cfg), zap.String("email", email), zap.String("subject", subject), zap.String("body", body))
if !cfg.Enable {
return errors.New("邮件服务未启用")
}
fromName := cfg.Username
if fn := strings.TrimSpace(cfg.FromName); fn != "" {
fromName = fn
}
message := gomail.NewMessage()
message.SetHeader("From", message.FormatAddress(cfg.Username, fromName))
message.SetHeader("To", email)
message.SetHeader("Subject", subject)
message.SetBody("text/html", body)
// if cfg.ReplyTo != "" {
// message.SetHeader("Reply-To", cfg.ReplyTo)
// }
mail := gomail.NewDialer(cfg.Host, cfg.Port, cfg.Username, cfg.Password)
if cfg.IsTLS {
mail.TLSConfig = &tls.Config{InsecureSkipVerify: true}
}
return mail.DialAndSend(message)
}
func (m *DBModel) initConfig() (err error) {
// 初始化配置项
cfgs := []Config{
@ -592,6 +676,17 @@ func (m *DBModel) initConfig() (err error) {
{Category: ConfigCategoryScore, Name: ConfigScoreDocumentCollectedLimit, Label: "每日文档被收藏奖励次数", Value: "1", Placeholder: "每天最多可以获得多少次文档被收藏奖励0表示无奖励。", InputType: "number", Sort: 60, Options: ""},
{Category: ConfigCategoryScore, Name: ConfigScoreDocumentCommented, Label: "文档被评论", Value: "1", Placeholder: "上传的文档被评论后获得的魔豆", InputType: "number", Sort: 70, Options: ""},
{Category: ConfigCategoryScore, Name: ConfigScoreDocumentCommentedLimit, Label: "每日文档被评论奖励次数", Value: "1", Placeholder: "每天最多可以获得多少次文档被评论奖励0表示无奖励。", InputType: "number", Sort: 80, Options: ""},
// 邮件配置
{Category: ConfigCategoryEmail, Name: ConfigEmailEnable, Label: "是否启用邮件服务", Value: "false", Placeholder: "邮件服务,用于找回账户密码", InputType: "switch", Sort: 10, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailHost, Label: "SMTP 服务器地址", Value: "", Placeholder: "如smtp.exmail.com", InputType: "text", Sort: 20, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailPort, Label: "SMTP 服务器端口", Value: "465", Placeholder: "如465", InputType: "number", Sort: 30, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailIsTLS, Label: "是否启用TLS", Value: "true", Placeholder: "如果是TLS端口请启用", InputType: "switch", Sort: 40, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailFromName, Label: "发件人名称", Value: "", Placeholder: "请输入您要展示的发件人名称", InputType: "text", Sort: 50, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailUsername, Label: "SMTP 账号", Value: "", Placeholder: "请输入您的邮箱账户", InputType: "text", Sort: 60, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailPassword, Label: "SMTP 密码", Value: "", Placeholder: "请输入您的邮箱密码", InputType: "password", Sort: 70, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailDuration, Label: "邮件有效期", Value: "30", Placeholder: "找回密码时链接有效期默认为30表示30分钟", InputType: "number", Sort: 80, Options: ""},
{Category: ConfigCategoryEmail, Name: ConfigEmailTestEmail, Label: "测试邮箱", Value: "", Placeholder: "用于每次变更配置时保存发送测试邮件", InputType: "text", Sort: 90, Options: ""},
}
for _, cfg := range cfgs {

@ -120,12 +120,11 @@ export default {
if (res.status === 200) {
this.$message.success('配置更新成功')
} else {
this.$message.error('配置更新失败')
this.$message.error(res.data.message || '配置更新失败')
}
this.loading = false
},
success(res, index) {
console.log(res, index)
this.configs[index] = { ...this.configs[index], value: res.data.path }
},
},

@ -61,6 +61,10 @@ export default {
label: '积分配置',
value: 'score',
},
{
label: '邮箱配置',
value: 'email',
},
],
}
},

Loading…
Cancel
Save