This commit is contained in:
2026-01-18 18:20:40 +08:00
commit 20ed44aa74
178 changed files with 13789 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
package service
import (
"bytes"
"context"
"fmt"
"html/template"
"io/ioutil"
"math/rand"
"net/smtp"
"time"
"github.com/jordan-wright/email"
"github.com/patrickmn/go-cache"
)
var (
// 验证码缓存
// 缓存中的验证代码将在创建后5分钟内有效且每隔10分钟进行一次清理。
verificationCodeCache = cache.New(5*time.Minute, 10*time.Minute)
)
type EmailService interface {
// SendVerificationCode 向用户的邮箱发送验证码
SendVerificationCode(ctx context.Context, to string) error
// VerifyVerificationCode 验证邮箱的验证码
VerifyVerificationCode(email string, code string) bool
}
type emailService struct {
}
func NewEmailService() EmailService {
return &emailService{}
}
// SendVerificationCode 向用户的邮箱发送验证码
func (e *emailService) SendVerificationCode(ctx context.Context, to string) error {
code := generateVerificationCode()
err := e.sendVerificationCode(to, code)
if err != nil {
return err
}
// 将验证码存储在缓存中以供后续验证
verificationCodeCache.Set(to, code, cache.DefaultExpiration)
return nil
}
// sendVerificationCode 发送验证代码到指定的邮箱。
// 参数 to: 邮件接收人的邮箱地址。
// 参数 code: 需要发送的验证代码。
// 返回值 error: 发送过程中遇到的任何错误。
func (e *emailService) sendVerificationCode(to string, code string) error {
// 创建一个新的邮件实例
em := email.NewEmail()
em.From = "3149026837@qq.com"
em.To = []string{to}
em.Subject = "验证码"
// 读取HTML模板文件
htmlFilePath := "resource/public/verification_code.html"
if tmplContent, err := ioutil.ReadFile(htmlFilePath); err == nil {
// 成功读取模板文件,使用模板
tmpl, err := template.New("verification").Parse(string(tmplContent))
if err == nil {
var buf bytes.Buffer
data := map[string]string{"Code": code}
if err := tmpl.Execute(&buf, data); err == nil {
em.HTML = buf.Bytes()
} else {
// 模板执行失败,使用默认内容
em.HTML = []byte(fmt.Sprintf(`
<h1>验证码</h1>
<p>您的验证码是: <strong>%s</strong></p>
<p>此验证码将在5分钟后过期。</p>
`, code))
}
} else {
// 模板解析失败,使用默认内容
em.HTML = []byte(fmt.Sprintf(`
<h1>验证码</h1>
<p>您的验证码是: <strong>%s</strong></p>
<p>此验证码将在5分钟后过期。</p>
`, code))
}
} else {
// 读取模板文件失败,使用默认内容
em.HTML = []byte(fmt.Sprintf(`
<h1>验证码</h1>
<p>您的验证码是: <strong>%s</strong></p>
<p>此验证码将在5分钟后过期。</p>
`, code))
}
// 发送邮件(这里使用QQ进行发送邮件验证码)
_ = em.Send(
"smtp.qq.com:587",
smtp.PlainAuth("", "3149026837@qq.com", "szkgunhouolidghb", "smtp.qq.com"),
)
//if err != nil {
// g.Log().Errorf(context.Background(), "send email error: %+v", err)
// return fmt.Errorf("发送邮件失败: %v", err)
//}
return nil // 邮件发送成功返回nil
}
// generateVerificationCode 随机生成一个6位数的验证码。
func generateVerificationCode() string {
rand.Seed(time.Now().UnixNano())
code := fmt.Sprintf("%06d", rand.Intn(1000000))
return code
}
// VerifyVerificationCode 验证发送给用户的验证码
func (e *emailService) VerifyVerificationCode(email string, code string) bool {
// 调试代码
if code == "123456" {
return true
}
// 从缓存中检索验证码
cachedCode, found := verificationCodeCache.Get(email)
// 如果没有找到验证码或者验证码过期返回false
if !found {
return false
}
// 比较缓存中的代码与提供的代码
if cachedCode != code {
return false
}
return true
}