/* Copyright 2026 linux.do Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package user import ( "context" "encoding/json" "errors" "fmt" "strconv" "github.com/linux-do/credit/internal/model" "github.com/linux-do/credit/internal/task" "github.com/linux-do/credit/internal/util/mail" ) // SendEmailPayload 邮件发送任务载荷 type SendEmailPayload struct { To string `json:"to"` Subject string `json:"subject"` Body string `json:"body"` } // SendEmailHandler 发送验证码邮件的异步任务处理器 type SendEmailHandler struct{} // Execute 执行邮件异步发送逻辑 func (h *SendEmailHandler) Execute(ctx context.Context, payload []byte) (*task.TaskResult, error) { var req SendEmailPayload if err := json.Unmarshal(payload, &req); err != nil { task.AppendLog(ctx, "解析邮件发送参数失败: %v", err) return nil, fmt.Errorf("解析邮件发送参数失败: %w", err) } task.AppendLog(ctx, "开始准备发送邮件到: %s, 主题: %s", req.To, req.Subject) // 从数据库读取最新的 SMTP 系统配置 var smtpHost string var smtpPortVal string var smtpUsername string var smtpPassword string var sc model.SystemConfig if err := sc.GetByKey(ctx, model.ConfigKeySMTPHost); err == nil { smtpHost = sc.Value } if err := sc.GetByKey(ctx, model.ConfigKeySMTPPort); err == nil { smtpPortVal = sc.Value } if err := sc.GetByKey(ctx, model.ConfigKeySMTPUsername); err == nil { smtpUsername = sc.Value } if err := sc.GetByKey(ctx, model.ConfigKeySMTPPassword); err == nil { smtpPassword = sc.Value } if smtpHost == "" || smtpPortVal == "" || smtpUsername == "" { err := errors.New("系统 SMTP 邮件服务配置不完整") task.AppendLog(ctx, "发送失败: %v", err) return nil, err } smtpPort, err := strconv.Atoi(smtpPortVal) if err != nil { smtpPort = 587 } cfg := mail.Config{ Host: smtpHost, Port: smtpPort, Username: smtpUsername, Password: smtpPassword, } task.AppendLog(ctx, "连接 SMTP 服务器: %s:%d, 用户名: %s", smtpHost, smtpPort, smtpUsername) // 调用 SendMailHTML 执行邮件发送,这里会有 5s 拨号超时和 10s 读写限制 err = mail.SendMailHTML(cfg, req.To, req.Subject, req.Body) if err != nil { task.AppendLog(ctx, "邮件发送失败: %v", err) return nil, fmt.Errorf("发送邮件失败: %w", err) } msg := fmt.Sprintf("邮件成功发送至: %s", req.To) task.AppendLog(ctx, "%s", msg) return &task.TaskResult{ Message: msg, }, nil }