using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace OASystem.API.OAMethodLib.HotmailEmail { public class HotmailEmailService : IHotmailEmailService { private readonly IConfiguration _config; private readonly ILogger _logger; public HotmailEmailService(IConfiguration config, ILogger logger) { _config = config; _logger = logger; } public async Task SendEmailAsync(string toEmail, string subject, string htmlContent) { // 1. 配置前置校验 string smtpServer = _config["HotEmailConfig:SmtpServer"] ?? string.Empty; int smtpPort = _config.GetValue("HotEmailConfig:SmtpPort", 587); string appPassword = _config["HotEmailConfig:AppPassword"]; string senderEmail = _config["HotEmailConfig:SenderEmail"]; string senderName = _config["HotEmailConfig:SenderName"]; if (string.IsNullOrEmpty(smtpServer) || string.IsNullOrEmpty(appPassword)) { _logger.LogError("[Config Alchemy] 无法从 JSON 获取必要的邮件配置节点。"); return false; } // 2. 构建邮件内容 var message = new MimeMessage(); message.From.Add(new MailboxAddress(senderName, senderEmail)); if (!MailboxAddress.TryParse(toEmail, out var recipient)) { _logger.LogWarning("[Email] 收件人地址非法: {ToEmail}", toEmail); return false; } message.To.Add(recipient); message.Subject = subject; var bodyBuilder = new BodyBuilder { HtmlBody = htmlContent }; message.Body = bodyBuilder.ToMessageBody(); // 3. 客户端连接与发送 using var client = new SmtpClient(); try { // Hotmail/Outlook 通常使用 587 + StartTls 或 465 + SslOnConnect var secureOption = smtpPort == 465 ? SecureSocketOptions.SslOnConnect : SecureSocketOptions.StartTls; // 设置超时 (建议 30-60 秒) client.Timeout = 30000; await client.ConnectAsync(smtpServer, smtpPort, secureOption); await client.AuthenticateAsync(senderEmail, appPassword); await client.SendAsync(message); await client.DisconnectAsync(true); _logger.LogInformation("[Email] 成功发送至: {ToEmail}", toEmail); return true; } catch (Exception ex) { _logger.LogError(ex, "[Email] 发送失败,目标: {ToEmail}", toEmail); return false; } } } }