|
|
@@ -1,6 +1,9 @@
|
|
|
using Quartz;
|
|
|
using OASystem.API.OAMethodLib.QiYeWeChatAPI;
|
|
|
using OASystem.Domain.ViewModels.QiYeWeChat;
|
|
|
+using Newtonsoft.Json;
|
|
|
+using Newtonsoft.Json.Linq;
|
|
|
+using Microsoft.AspNetCore.Http;
|
|
|
|
|
|
namespace OASystem.API.OAMethodLib.Quartz.Jobs
|
|
|
{
|
|
|
@@ -45,6 +48,13 @@ namespace OASystem.API.OAMethodLib.Quartz.Jobs
|
|
|
{
|
|
|
var keyUser = await _sqlSugar.Queryable<Sys_Users>()
|
|
|
.FirstAsync(x => x.Id == item);
|
|
|
+
|
|
|
+ if (keyUser == null || string.IsNullOrEmpty(keyUser.Email))
|
|
|
+ {
|
|
|
+ _logger.LogWarning($"管理者(ID:{item})不存在或未配置邮箱,跳过发送汇总邮件。");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
var users = await _sqlSugar.Queryable<Sys_Users>()
|
|
|
.LeftJoin<Sys_Department>((u, d) => u.DepId == d.Id)
|
|
|
.LeftJoin<Sys_JobPost>((u, d, jp) => u.JobPostId == jp.Id)
|
|
|
@@ -52,6 +62,9 @@ namespace OASystem.API.OAMethodLib.Quartz.Jobs
|
|
|
.Select((u, d, jp) => new { u.Id, u.CnName, DepName = d.DepName ?? "", JobName = jp.JobName ?? "" })
|
|
|
.ToListAsync();
|
|
|
|
|
|
+ // 用于收集该管理者下所有员工的附件
|
|
|
+ var attachments = new List<IFormFile>();
|
|
|
+
|
|
|
foreach (var user in users)
|
|
|
{
|
|
|
// 构建API URL
|
|
|
@@ -72,7 +85,6 @@ namespace OASystem.API.OAMethodLib.Quartz.Jobs
|
|
|
string fullUrl = $"{apiUrl}?{queryString}";
|
|
|
|
|
|
_logger.LogInformation($"正在为用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 生成绩效数据...");
|
|
|
- _logger.LogInformation($"API URL: {fullUrl}");
|
|
|
|
|
|
// 发送HTTP GET请求
|
|
|
var response = await _httpClient.GetAsync(fullUrl);
|
|
|
@@ -80,7 +92,6 @@ namespace OASystem.API.OAMethodLib.Quartz.Jobs
|
|
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
|
{
|
|
|
- // 尝试解析响应结果
|
|
|
try
|
|
|
{
|
|
|
var resultJson = JsonConvert.DeserializeObject<JsonView>(responseContent);
|
|
|
@@ -89,7 +100,6 @@ namespace OASystem.API.OAMethodLib.Quartz.Jobs
|
|
|
_logger.LogInformation($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 绩效数据生成成功");
|
|
|
//生成PDF
|
|
|
var url = $"{baseUrl}/api/PersonnelModule/AiPerformanceAnalysis_JobMarketingFileDown";
|
|
|
- //构建PDF查询参数
|
|
|
var queryParamsPdf = new Dictionary<string, string>
|
|
|
{
|
|
|
{ "userId", user.Id.ToString() },
|
|
|
@@ -106,52 +116,65 @@ namespace OASystem.API.OAMethodLib.Quartz.Jobs
|
|
|
|
|
|
if (pdfUrl.IsSuccessStatusCode)
|
|
|
{
|
|
|
- _logger.LogInformation($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 开始生成PDF:{pdfUrl.StatusCode}");
|
|
|
var pdfContent = await pdfUrl.Content.ReadAsStringAsync();
|
|
|
- _logger.LogInformation($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 绩效数据生成PDF成功:{pdfContent}");
|
|
|
var pdfContentJson = JObject.Parse(pdfContent);
|
|
|
var pdfUrlString = pdfContentJson["data"]["url"].ToString();
|
|
|
var pdfUrlSeed = new Uri(pdfUrlString);
|
|
|
var pdfBytes = await _httpClient.GetByteArrayAsync(pdfUrlSeed);
|
|
|
- var fileName = pdfUrlString.Split('/').Last();
|
|
|
- var pdfFile = new FormFile(new MemoryStream(pdfBytes), 0, pdfBytes.Length, fileName, fileName);
|
|
|
|
|
|
- _logger.LogInformation($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName})文件大小:{pdfFile.Length}");
|
|
|
+ // 提取文件名并重命名以包含员工姓名,方便管理者识别
|
|
|
+ var originalFileName = pdfUrlString.Split('/').Last();
|
|
|
+ var fileName = $"{originalFileName}";
|
|
|
+
|
|
|
+ var pdfFile = new FormFile(new MemoryStream(pdfBytes), 0, pdfBytes.Length, fileName, fileName);
|
|
|
|
|
|
- var resultEmail = await _qiYeWeChatApiService.EmailSendAsync(new EmailRequestDto
|
|
|
- {
|
|
|
- ToEmails = new List<string> { keyUser.Email },
|
|
|
- Subject = $"用户 {user.CnName}(部门:{user.DepName} 日期区间:{startDate.ToString("yyyy-MM-dd")} 至 {endDate.ToString("yyyy-MM-dd")}) 绩效数据",
|
|
|
- Body = "员工绩效推送,请查看附件。",
|
|
|
- Files = new[] { pdfFile }
|
|
|
- });
|
|
|
+ _logger.LogInformation($"用户 {user.CnName}(ID:{user.Id}) PDF生成成功,大小:{pdfFile.Length},已加入待发送列表");
|
|
|
|
|
|
- _logger.LogInformation($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 发送邮件成功:{resultEmail.errcode}, {resultEmail.errmsg}");
|
|
|
+ // 将附件添加到列表
|
|
|
+ attachments.Add(pdfFile);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
-
|
|
|
- _logger.LogWarning($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 生成PDF失败:{pdfUrl.StatusCode}");
|
|
|
- _logger.LogWarning($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 生成PDF失败:{pdfUrl.Content.ReadAsStringAsync()}");
|
|
|
+ _logger.LogWarning($"用户 {user.CnName}(ID:{user.Id}) 生成PDF失败:{pdfUrl.StatusCode}");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- _logger.LogWarning($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 绩效数据生成失败:{resultJson?.Msg ?? "未知错误"}");
|
|
|
+ _logger.LogWarning($"用户 {user.CnName}(ID:{user.Id}) 绩效数据生成失败:{resultJson?.Msg ?? "未知错误"}");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- _logger.LogError(ex, $"解析用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 的API响应失败");
|
|
|
+ _logger.LogError(ex, $"处理用户 {user.CnName}(ID:{user.Id}) 时发生异常");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- _logger.LogError($"用户 {user.CnName}(ID:{user.Id}, 部门:{user.DepName}) 绩效数据生成API调用失败,状态码: {response.StatusCode}, 响应内容: {responseContent}");
|
|
|
+ _logger.LogError($"用户 {user.CnName}(ID:{user.Id}) 绩效数据生成API调用失败,状态码: {response.StatusCode}");
|
|
|
}
|
|
|
|
|
|
// 添加延迟,避免请求过于频繁
|
|
|
- await Task.Delay(3000); // 延迟3秒
|
|
|
+ await Task.Delay(3000);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果该管理者有附件,则一次性发送一封汇总邮件
|
|
|
+ if (attachments.Any())
|
|
|
+ {
|
|
|
+ _logger.LogInformation($"正在为管理者 {keyUser.CnName} 发送汇总邮件,附件数量:{attachments.Count}");
|
|
|
+
|
|
|
+ var resultEmail = await _qiYeWeChatApiService.EmailSendAsync(new EmailRequestDto
|
|
|
+ {
|
|
|
+ ToEmails = new List<string> { keyUser.Email },
|
|
|
+ Subject = $"员工绩效数据汇总({startDate:yyyy-MM-dd} 至 {endDate:yyyy-MM-dd})",
|
|
|
+ Body = $"您好,附件中包含您负责的 {attachments.Count} 位员工的周绩效报告,请查收。",
|
|
|
+ Files = attachments.ToArray()
|
|
|
+ });
|
|
|
+
|
|
|
+ _logger.LogInformation($"管理者 {keyUser.CnName} 汇总邮件发送结果:{resultEmail.errcode}, {resultEmail.errmsg}");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _logger.LogWarning($"管理者 {keyUser.CnName} 没有生成的绩效附件,跳过发送邮件。");
|
|
|
}
|
|
|
}
|
|
|
}
|