Explorar el Código

hotmail 代码编写

Lyyyi hace 2 semanas
padre
commit
97bfa851b8

+ 34 - 2
OASystem/OASystem.Api/Controllers/AITestController.cs

@@ -1,9 +1,10 @@
 using Microsoft.AspNetCore.Mvc;
-using System.IO;
 using OASystem.API.OAMethodLib.DoubaoAPI;
+using OASystem.API.OAMethodLib.HotmailEmail;
 using OASystem.API.OAMethodLib.HunYuanAPI;
 using OASystem.API.OAMethodLib.QiYeWeChatAPI;
 using OASystem.Domain.ViewModels.QiYeWeChat;
+using System.IO;
 using TencentCloud.Hunyuan.V20230901.Models;
 
 namespace OASystem.API.Controllers
@@ -18,13 +19,15 @@ namespace OASystem.API.Controllers
         private readonly IDoubaoService _doubaoService;
         private readonly ILogger<AITestController> _logger;
         private readonly IQiYeWeChatApiService _qiYeWeChatApiService;
+        private readonly IHotmailEmailService _hotmailEmailService;
 
-        public AITestController(IHunyuanService hunyuanService, IDoubaoService doubaoService, ILogger<AITestController> logger, IQiYeWeChatApiService qiYeWeChatApiService)
+        public AITestController(IHunyuanService hunyuanService, IDoubaoService doubaoService, ILogger<AITestController> logger, IQiYeWeChatApiService qiYeWeChatApiService, IHotmailEmailService hotmailEmailService)
         {
             _hunyuanService = hunyuanService;
             _doubaoService = doubaoService;
             _logger = logger;
             _qiYeWeChatApiService = qiYeWeChatApiService;
+            _hotmailEmailService = hotmailEmailService;
         }
 
         #region 企业微信发送邮件测试
@@ -320,5 +323,34 @@ namespace OASystem.API.Controllers
         }
         #endregion
 
+        #region hotmail 测试
+        [HttpPost("send-notification")]
+        public async Task<IActionResult> SendNotification([FromBody] EmailRequest request)
+        {
+            if (string.IsNullOrEmpty(request.Email))
+                return BadRequest("邮箱地址不能为空");
+
+            // 调用服务
+            bool isSent = await _hotmailEmailService.SendEmailAsync(
+                request.Email,
+                "OASystem 业务提醒",
+                $"<p>您有一条新的待办事项:<b>{request.Content}</b></p>"
+            );
+
+            if (isSent)
+                return Ok(new { code = 200, msg = "发送成功" });
+
+            return StatusCode(500, "邮件发送失败,请检查服务器配置或应用密码");
+        }
+
+        // 定义请求实体
+        public class EmailRequest
+        {
+            public string Email { get; set; } = string.Empty;
+            public string Content { get; set; } = string.Empty;
+        }
+
+        #endregion
+
     }
 }

+ 12 - 13
OASystem/OASystem.Api/Controllers/ResourceController.cs

@@ -2715,7 +2715,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 var hunyuanAIInvDatas = new List<InvitationAIInfo>();
                 if (aiTasks.Any())
                 {
-                    await SendStep(60, $"正在召唤混元 AI:检索 {aiTasks.Count} 个国家的邀请信息...");
+                    await SendStep(60, $"Hunyuan AI 正在跨境深度检索 {aiTasks.Count} 个国家的邀请单位信息...");
 
                     string question = BuildHunyuanPrompt(aiTasks, entryInfo); // 抽离 Prompt 构造
                     string aiRawResponse = string.Empty;
@@ -2743,8 +2743,8 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                     }
                     catch (Exception ex)
                     {
-                        _logger.LogError(ex, "AI 接口调用或解析失败");
-                        await SendStep(60, "警告:AI 检索部分失败,将仅展示本地数据。");
+                        _logger.LogError(ex, "Hunyuan AI 接口调用或解析失败");
+                        await SendStep(60, "警告:Hunyuan AI 检索部分失败,将仅展示本地数据。");
                     }
                 }
                 #endregion
@@ -2775,7 +2775,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
             catch (Exception ex)
             {
                 _logger.LogError(ex, "SSE 发生不可预知异常");
-                await SendStep(-1, $"炼金炸炉:{ex.Message}");
+                await SendStep(-1, $"SSE Error:{ex.Message}");
             }
             finally
             {
@@ -2783,9 +2783,9 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 await HttpContext.Response.Body.FlushAsync();
 
                 // 此时方法结束,ASP.NET Core 会自动处理连接关闭
-                _logger.LogInformation("SSE 炼金通道已安全关闭");
-                // :直接完成响应流
+                _logger.LogInformation("SSE 通道已安全关闭");
 
+                // 直接完成响应流
                 await response.CompleteAsync();
 
             }
@@ -3374,8 +3374,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 {
                     progress,
                     message = msg,
-                    data,
-                    operatedAt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
+                    data
                 });
                 await response.WriteAsync($"data: {payload}\n\n");
                 await response.Body.FlushAsync();
@@ -3418,7 +3417,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 // 构建 Question 
                 string question = BuildHunyuanPrompt(aiTasks, entryInfo);
 
-                await SendStep(30, "AI 正在深度检索跨境商邀数据,请稍候...");
+                await SendStep(30, "Hunyuan AI 正在深度检索跨境商邀数据,请稍候...");
 
                 // 调用 AI (Progress: 30% - 80%)
                 // 注意:这里如果能换成流式接口(ChatCompletionsStream)会更好,
@@ -3447,7 +3446,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
 
                 if (update > 0)
                 {
-                    await SendStep(100, $"AI 续写成功!新增 {hunyuanAIInvDatas.Count} 条数据", invAiInfo.AiCrawledDetails);
+                    await SendStep(100, $"Hunyuan AI 续写成功!新增 {hunyuanAIInvDatas.Count} 条数据", invAiInfo.AiCrawledDetails);
                 }
                 else
                 {
@@ -3974,7 +3973,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                     return;
                 }
 
-                await SendStep(10, "正在分析考察团组背景与访问意图...");
+                await SendStep(10, "Hunyuan AI 正在分析考察团组背景与访问意图...");
 
                 // 2. 准备 AI 上下文数据 (Progress: 15%)
                 var clientInfoSources = invAiInfo.AiCrawledDetails.Where(x => dto.Guids.Contains(x.Guid)).ToList();
@@ -3994,7 +3993,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                     .Where(x => x.Id == dto.CurrUserId).Select(x => x.CnName).FirstAsync() ?? "-";
 
                 // 3. 构建 Prompt 并调用 AI (Progress: 25%)
-                await SendStep(30, $"首席联络官已就位,正在为 {clientInfosForAI.Count} 家单位撰写定制化正式邮件...");
+                await SendStep(30, $"Hunyuan AI 正在为 {clientInfosForAI.Count} 家单位撰写定制化正式邮件...");
 
                 // 此处沿用你原有的庞大 Prompt 逻辑
                 string pormpt = $@"
@@ -4072,7 +4071,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
                 // 4. 解析结果 (Progress: 85%)
                 var hunyuanAIEmailDatas = new List<AICreateEmailInfo>();
                 if (!string.IsNullOrWhiteSpace(aiResponse))
-            {
+                {
                     // 预处理:过滤 AI 可能返回的 Markdown 标记
                     string cleanJson = aiResponse.Trim();
                     if (cleanJson.StartsWith("```json"))

+ 45 - 30
OASystem/OASystem.Api/OAMethodLib/HotmailEmail/HotmailEmailService.cs

@@ -1,44 +1,59 @@
 
-using System.Net;
-using System.Net.Mail;
+using MailKit.Net.Smtp;
+using MailKit.Security;
+using MimeKit;
 
 namespace OASystem.API.OAMethodLib.HotmailEmail
 {
     /// <summary>
     /// Hotemail 服务
     /// </summary>
-    public class HotmailEmailService
+    public class HotmailEmailService : IHotmailEmailService
     {
-        private readonly string _hotmailEmail = "your-email@hotmail.com";
-        private readonly string _appPassword = "your-app-specific-password"; // 不是你的登录密码,是应用专用密码
+        private readonly IConfiguration _configuration;
 
-        public async Task SendEmailAsync(string targetEmail, string subject, string body)
+        public HotmailEmailService(IConfiguration configuration)
         {
-            using (var client = new SmtpClient("smtp.office365.com", 587))
+            _configuration = configuration;
+        }
+
+        public async Task<bool> SendEmailAsync(string toEmail, string subject, string htmlContent)
+        {
+            // 从配置读取信息
+            var smtpServer = _configuration["HotEmailConfig:SmtpServer"];
+            var smtpPort = int.Parse(_configuration["HotEmailConfig:SmtpPort"]);
+            var senderEmail = _configuration["HotEmailConfig:SenderEmail"];
+            var senderName = _configuration["HotEmailConfig:SenderName"];
+            var appPassword = _configuration["HotEmailConfig:AppPassword"];
+
+            var message = new MimeMessage();
+            message.From.Add(new MailboxAddress(senderName, senderEmail));
+            message.To.Add(new MailboxAddress("", toEmail));
+            message.Subject = subject;
+
+            var bodyBuilder = new BodyBuilder { HtmlBody = htmlContent };
+            message.Body = bodyBuilder.ToMessageBody();
+
+            using var client = new SmtpClient();
+            try
+            {
+                // 连接服务器 (Hotmail/Outlook 必须使用 StartTls)
+                await client.ConnectAsync(smtpServer, smtpPort, SecureSocketOptions.StartTls);
+
+                // 身份验证
+                await client.AuthenticateAsync(senderEmail, appPassword);
+
+                // 执行发送
+                await client.SendAsync(message);
+                await client.DisconnectAsync(true);
+
+                return true;
+            }
+            catch (Exception ex)
             {
-                client.EnableSsl = true;
-                client.UseDefaultCredentials = false;
-                client.Credentials = new NetworkCredential(_hotmailEmail, _appPassword);
-
-                var mailMessage = new MailMessage
-                {
-                    From = new MailAddress(_hotmailEmail, "商邀联络官"),
-                    Subject = subject,
-                    Body = body,
-                    IsBodyHtml = true // 如果内容是 HTML 格式
-                };
-
-                mailMessage.To.Add(targetEmail);
-
-                try
-                {
-                    await client.SendMailAsync(mailMessage);
-                }
-                catch (Exception ex)
-                {
-                    // 记录日志:ex.Message
-                    throw;
-                }
+                // 这里可以记录到你的 OASystem 日志库
+                Console.WriteLine($"[Email Error]: {ex.Message}");
+                return false;
             }
         }
     }

+ 7 - 0
OASystem/OASystem.Api/OAMethodLib/HotmailEmail/IHotmailEmailService.cs

@@ -0,0 +1,7 @@
+namespace OASystem.API.OAMethodLib.HotmailEmail
+{
+    public interface IHotmailEmailService
+    {
+        Task<bool> SendEmailAsync(string toEmail, string subject, string htmlContent);
+    }
+}

+ 1 - 0
OASystem/OASystem.Api/OASystem.API.csproj

@@ -54,6 +54,7 @@
     <PackageReference Include="Flurl.Http" Version="3.2.4" />
     <PackageReference Include="iTextSharp" Version="5.5.13.5" />
     <PackageReference Include="JsonDiffPatch.Net" Version="2.3.0" />
+    <PackageReference Include="MailKit" Version="4.15.1" />
     <PackageReference Include="Markdig" Version="0.33.0" />
     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.11" />
     <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.0" />

+ 5 - 0
OASystem/OASystem.Api/Program.cs

@@ -11,6 +11,7 @@ using OASystem.API.OAMethodLib.AMapApi;
 using OASystem.API.OAMethodLib.APNs;
 using OASystem.API.OAMethodLib.DeepSeekAPI;
 using OASystem.API.OAMethodLib.GenericSearch;
+using OASystem.API.OAMethodLib.HotmailEmail;
 using OASystem.API.OAMethodLib.Hub.Hubs;
 using OASystem.API.OAMethodLib.HunYuanAPI;
 using OASystem.API.OAMethodLib.JuHeAPI;
@@ -592,6 +593,10 @@ builder.Services.AddSignalR()
 builder.Services.TryAddSingleton(typeof(CommonService));
 #endregion
 
+#region hotmail
+builder.Services.AddTransient<IHotmailEmailService, HotmailEmailService>();
+#endregion
+
 var app = builder.Build();
 
 //// 1. 异常处理器应该在最早的位置(除了日志等)

+ 8 - 0
OASystem/OASystem.Api/appsettings.json

@@ -596,5 +596,13 @@
     "AppId": 100015480940,
     "Region": "ap-chengdu",
     "Version": "2023-09-01"
+  },
+   // 邮件发送配置
+  "HotEmailConfig": {
+    "SmtpServer": "smtp.office365.com",
+    "SmtpPort": 587,
+    "SenderEmail": "Roy.Lei.Atom@hotmail.com",
+    "SenderName": "Roy Lei",
+    "AppPassword": "K3U5X-4W79Y-FP2JU-X25DB-6U9DU"
   }
 }