using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
using NPP.SmartSchedue.Api.Contracts.Services.Notification;
using NPP.SmartSchedue.Api.Contracts.Services.Notification.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Notification.Output;
using NPP.SmartSchedue.Api.Contracts.Domain.Notification;
using NPP.SmartSchedue.Api.Repositories.Notification;
using NPP.SmartSchedue.Api.Contracts.Core.Enums;
using NPP.SmartSchedue.Api.Core.Consts;
using ZhonTai.Admin.Core.GrpcServices;
using ZhonTai.Admin.Core.GrpcServices.Dtos;
namespace NPP.SmartSchedue.Api.Services.Notification;
///
/// 通知服务
///
[DynamicApi(Area = "app")]
public class NotificationService : BaseService, INotificationService, IDynamicApi
{
private readonly NotificationSettingRepository _notificationSettingRepository;
private readonly PersonnelGroupRepository _personnelGroupRepository;
private readonly NotificationHistoryRepository _notificationHistoryRepository;
private readonly IEmailNotificationService _emailNotificationService;
private readonly ISystemMessageService _systemMessageService;
private readonly INotificationTemplateService _templateService;
private readonly IUserGrpcService _userService;
private readonly ILogger _logger;
public NotificationService(
NotificationSettingRepository notificationSettingRepository,
PersonnelGroupRepository personnelGroupRepository,
NotificationHistoryRepository notificationHistoryRepository,
IEmailNotificationService emailNotificationService,
ISystemMessageService systemMessageService,
INotificationTemplateService templateService,
IUserGrpcService userService,
ILogger logger)
{
_notificationSettingRepository = notificationSettingRepository;
_personnelGroupRepository = personnelGroupRepository;
_notificationHistoryRepository = notificationHistoryRepository;
_emailNotificationService = emailNotificationService;
_systemMessageService = systemMessageService;
_templateService = templateService;
_userService = userService;
_logger = logger;
}
#region 通知设置管理
///
/// 获取通知设置列表(可选过滤,含缓存)
///
[HttpGet]
public async Task> GetNotificationSettingListAsync(bool? isEnabled = null, long? personnelGroupId = null)
{
var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
var cachedList = await Cache.GetAsync>(cacheKey);
if ( cachedList != null && cachedList.Any())
{
return cachedList;
}
var query = _notificationSettingRepository.Select.Include(a => a.PersonnelGroup);
if (isEnabled != null)
{
query = query.Where(a => a.IsEnabled == isEnabled);
}
if (personnelGroupId.HasValue && personnelGroupId.Value > 0)
{
query = query.Where(a => a.PersonnelGroupId == personnelGroupId.Value);
}
var entities = await query.OrderByDescending(a => a.CreatedTime).ToListAsync();
var outputs = entities.Select(MapToNotificationSettingOutput).ToList();
Cache.Set(cacheKey, outputs, TimeSpan.FromHours(12));
return outputs;
}
///
/// 查询通知设置
///
[HttpGet]
public async Task GetNotificationSettingAsync(long id)
{
_logger.LogInformation("开始查询通知设置,ID:{Id}", id);
var entity = await _notificationSettingRepository.Select
.WhereDynamic(id)
.Include(a => a.PersonnelGroup)
.ToOneAsync();
if (entity == null)
{
_logger.LogWarning("通知设置不存在,ID:{Id}", id);
throw new Exception($"通知设置不存在,ID:{id}");
}
var output = MapToNotificationSettingOutput(entity);
_logger.LogInformation("成功查询通知设置,ID:{Id}", id);
return output;
}
///
/// 查询通知设置分页
///
[HttpPost]
public async Task> GetNotificationSettingPageAsync(PageInput input)
{
_logger.LogInformation("开始查询通知设置分页,页码:{Current},页大小:{Size}", input.CurrentPage, input.PageSize);
var query = _notificationSettingRepository.Select
.Include(a => a.PersonnelGroup);
// 根据搜索条件过滤
if (!string.IsNullOrEmpty(input.Filter?.NotificationName))
{
query = query.Where(a => a.NotificationName.Contains(input.Filter.NotificationName));
}
if (input.Filter?.IsEnabled != null)
{
query = query.Where(a => a.IsEnabled == input.Filter.IsEnabled);
}
if (input.Filter?.PersonnelGroupId != null && input.Filter.PersonnelGroupId > 0)
{
query = query.Where(a => a.PersonnelGroupId == input.Filter.PersonnelGroupId);
}
var totalCount = await query.CountAsync();
var entities = await query
.OrderByDescending(a => a.CreatedTime)
.Page(input.CurrentPage, input.PageSize)
.ToListAsync();
var outputs = entities.Select(MapToNotificationSettingOutput).ToList();
_logger.LogInformation("成功查询通知设置分页,总数:{Total},当前页数据:{Count}", totalCount, outputs.Count);
return new PageOutput
{
List = outputs,
Total = totalCount
};
}
///
/// 创建通知设置
///
[HttpPost]
public async Task CreateNotificationSettingAsync(NotificationSettingCreateInput input)
{
_logger.LogInformation("开始创建通知设置:{NotificationName}", input.NotificationName);
// 业务验证:检查通知设置名称是否已存在
var exists = await _notificationSettingRepository.ExistsNotificationNameAsync(input.NotificationName);
if (exists)
{
_logger.LogWarning("通知设置名称已存在:{NotificationName}", input.NotificationName);
throw new Exception($"通知设置名称已存在:{input.NotificationName}");
}
// 验证人员组是否存在
var personnelGroup = await _personnelGroupRepository.GetAsync(input.PersonnelGroupId);
if (personnelGroup == null)
{
_logger.LogWarning("人员组不存在,ID:{PersonnelGroupId}", input.PersonnelGroupId);
throw new Exception($"人员组不存在,ID:{input.PersonnelGroupId}");
}
// 业务验证:时间配置合法性检查
ValidateTimeConfiguration(input.StartTime, input.EndTime);
// 业务验证:频次配置合法性检查
ValidateFrequencyConfiguration(input.FrequencyType, input.IntervalMinutes);
// 业务验证:模板配置合法性检查
await ValidateTemplateConfiguration(input);
var entity = new NotificationSettingEntity
{
NotificationName = input.NotificationName,
Description = input.Description,
IsEnabled = input.IsEnabled,
StartTime = input.StartTime,
EndTime = input.EndTime,
FrequencyType = (int)input.FrequencyType,
IntervalMinutes = input.IntervalMinutes,
PersonnelGroupId = input.PersonnelGroupId,
EmailSubjectTemplate = input.EmailSubjectTemplate,
EmailContentTemplate = input.EmailContentTemplate,
SystemMessageTitleTemplate = input.SystemMessageTitleTemplate,
SystemMessageContentTemplate = input.SystemMessageContentTemplate,
TriggerConditions = input.TriggerConditions,
LastModifiedTime = DateTime.Now
};
// 设置通知方式
entity.IsEmailEnabled = input.IsEmailEnabled;
entity.IsSystemMessageEnabled = input.IsSystemMessageEnabled;
entity = await _notificationSettingRepository.InsertAsync(entity);
_logger.LogInformation("成功创建通知设置,ID:{Id},名称:{NotificationName}", entity.Id, entity.NotificationName);
var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
await ClearNotificationSettingCache();
return entity.Id;
}
///
/// 更新通知设置
///
[HttpPut]
public async Task UpdateNotificationSettingAsync(NotificationSettingUpdateInput input)
{
_logger.LogInformation("开始更新通知设置,ID:{Id}", input.Id);
var entity = await _notificationSettingRepository.GetAsync(input.Id);
if (entity == null)
{
_logger.LogWarning("通知设置不存在,ID:{Id}", input.Id);
throw new Exception($"通知设置不存在,ID:{input.Id}");
}
// 业务验证:检查通知设置名称是否已存在(排除自己)
var exists = await _notificationSettingRepository.ExistsNotificationNameAsync(input.NotificationName, input.Id);
if (exists)
{
_logger.LogWarning("通知设置名称已存在:{NotificationName}", input.NotificationName);
throw new Exception($"通知设置名称已存在:{input.NotificationName}");
}
// 验证人员组是否存在
var personnelGroup = await _personnelGroupRepository.GetAsync(input.PersonnelGroupId);
if (personnelGroup == null)
{
_logger.LogWarning("人员组不存在,ID:{PersonnelGroupId}", input.PersonnelGroupId);
throw new Exception($"人员组不存在,ID:{input.PersonnelGroupId}");
}
// 业务验证:时间配置合法性检查
ValidateTimeConfiguration(input.StartTime, input.EndTime);
// 业务验证:频次配置合法性检查
ValidateFrequencyConfiguration(input.FrequencyType, input.IntervalMinutes);
// 业务验证:模板配置合法性检查
await ValidateTemplateConfiguration(input);
// 更新实体属性
entity.NotificationName = input.NotificationName;
entity.Description = input.Description;
entity.IsEnabled = input.IsEnabled;
entity.StartTime = input.StartTime;
entity.EndTime = input.EndTime;
entity.FrequencyType = (int)input.FrequencyType;
entity.IntervalMinutes = input.IntervalMinutes;
entity.PersonnelGroupId = input.PersonnelGroupId;
entity.EmailSubjectTemplate = input.EmailSubjectTemplate;
entity.EmailContentTemplate = input.EmailContentTemplate;
entity.SystemMessageTitleTemplate = input.SystemMessageTitleTemplate;
entity.SystemMessageContentTemplate = input.SystemMessageContentTemplate;
entity.TriggerConditions = input.TriggerConditions;
entity.LastModifiedTime = DateTime.Now;
// 设置通知方式
entity.IsEmailEnabled = input.IsEmailEnabled;
entity.IsSystemMessageEnabled = input.IsSystemMessageEnabled;
await _notificationSettingRepository.UpdateAsync(entity);
_logger.LogInformation("成功更新通知设置,ID:{Id},名称:{NotificationName}", entity.Id, entity.NotificationName);
var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
await ClearNotificationSettingCache();
}
///
/// 删除通知设置
///
[HttpDelete]
public async Task DeleteNotificationSettingAsync(long id)
{
_logger.LogInformation("开始删除通知设置,ID:{Id}", id);
var entity = await _notificationSettingRepository.GetAsync(id);
if (entity == null)
{
_logger.LogWarning("通知设置不存在,ID:{Id}", id);
throw new Exception($"通知设置不存在,ID:{id}");
}
// 业务验证:检查是否存在关联的通知历史记录
var hasHistory = await _notificationHistoryRepository.Select
.Where(a => a.NotificationSettingId == id)
.AnyAsync();
if (hasHistory)
{
_logger.LogWarning("通知设置存在历史记录,无法删除,ID:{Id}", id);
throw new Exception($"通知设置存在历史记录,无法删除,ID:{id}");
}
await _notificationSettingRepository.DeleteAsync(id);
_logger.LogInformation("成功删除通知设置,ID:{Id},名称:{NotificationName}", id, entity.NotificationName);
await ClearNotificationSettingCache();
}
///
/// 启用/禁用通知设置
///
[HttpPut]
public async Task ToggleNotificationSettingAsync(long id, bool enabled)
{
_logger.LogInformation("开始{Action}通知设置,ID:{Id}", enabled ? "启用" : "禁用", id);
var entity = await _notificationSettingRepository.GetAsync(id);
if (entity == null)
{
_logger.LogWarning("通知设置不存在,ID:{Id}", id);
throw new Exception($"通知设置不存在,ID:{id}");
}
entity.IsEnabled = enabled;
entity.LastModifiedTime = DateTime.Now;
await _notificationSettingRepository.UpdateAsync(entity);
_logger.LogInformation("成功{Action}通知设置,ID:{Id},名称:{NotificationName}", enabled ? "启用" : "禁用", id, entity.NotificationName);
await ClearNotificationSettingCache();
}
///
/// 清除消息配置缓存
///
private async Task ClearNotificationSettingCache()
{
var cacheKey = $"{CacheKeys.NotificationSettingsKey}:all";
Cache.ExistsAsync(cacheKey);
}
#endregion
#region 人员组管理
///
/// 查询人员组
///
[HttpGet]
public async Task GetPersonnelGroupAsync(long id)
{
_logger.LogInformation("开始查询人员组,ID:{Id}", id);
var entity = await _personnelGroupRepository.Select
.WhereDynamic(id)
.ToOneAsync();
if (entity == null)
{
_logger.LogWarning("人员组不存在,ID:{Id}", id);
throw new Exception($"人员组不存在,ID:{id}");
}
var output = MapToPersonnelGroupOutput(entity);
// 计算实际人员数量
var actualCount = await GetPersonnelGroupMembersAsync(id);
output.TotalPersonnelCount = actualCount.Count;
_logger.LogInformation("成功查询人员组,ID:{Id},实际人员数量:{Count}", id, output.TotalPersonnelCount);
return output;
}
///
/// 查询人员组分页
///
[HttpPost]
public async Task> GetPersonnelGroupPageAsync(PageInput input)
{
_logger.LogInformation("开始查询人员组分页,页码:{Current},页大小:{Size}", input.CurrentPage, input.PageSize);
var query = _personnelGroupRepository.Select;
// 根据搜索条件过滤
if (!string.IsNullOrEmpty(input.Filter?.GroupName))
{
query = query.Where(a => a.GroupName.Contains(input.Filter.GroupName));
}
if (input.Filter?.IsEnabled != null)
{
query = query.Where(a => a.IsEnabled == input.Filter.IsEnabled);
}
if (input.Filter?.GroupType != null && input.Filter?.GroupType != 0)
{
query = query.Where(a => a.GroupType == (int)input.Filter.GroupType);
}
var totalCount = await query.CountAsync();
var entities = await query
.OrderByDescending(a => a.CreatedTime)
.Page(input.CurrentPage, input.PageSize)
.ToListAsync();
var outputs = entities.Select(MapToPersonnelGroupOutput).ToList();
// 批量计算实际人员数量
foreach (var output in outputs)
{
var actualMembers = await GetPersonnelGroupMembersAsync(output.Id);
output.TotalPersonnelCount = actualMembers.Count;
}
_logger.LogInformation("成功查询人员组分页,总数:{Total},当前页数据:{Count}", totalCount, outputs.Count);
return new PageOutput
{
List = outputs,
Total = totalCount
};
}
///
/// 创建人员组
///
[HttpPost]
public async Task CreatePersonnelGroupAsync(PersonnelGroupCreateInput input)
{
_logger.LogInformation("开始创建人员组:{GroupName}", input.GroupName);
// 业务验证:检查人员组名称是否已存在
var exists = await _personnelGroupRepository.ExistsGroupNameAsync(input.GroupName);
if (exists)
{
_logger.LogWarning("人员组名称已存在:{GroupName}", input.GroupName);
throw new Exception($"人员组名称已存在:{input.GroupName}");
}
// 业务验证:人员组配置合法性检查
ValidatePersonnelGroupConfiguration(input);
var entity = new PersonnelGroupEntity
{
GroupName = input.GroupName,
Description = input.Description,
GroupType = (int)input.GroupType,
IsEnabled = input.IsEnabled,
StaticPersonnelIds = JsonSerializer.Serialize(input.StaticPersonnelIds),
DynamicDepartmentIds = JsonSerializer.Serialize(input.DynamicDepartmentIds),
DynamicPositions = JsonSerializer.Serialize(input.DynamicPositions),
OnlyActivePersonnel = input.OnlyActivePersonnel,
ExcludePersonnelIds = JsonSerializer.Serialize(input.ExcludePersonnelIds),
LastModifiedTime = DateTime.Now
};
entity = await _personnelGroupRepository.InsertAsync(entity);
_logger.LogInformation("成功创建人员组,ID:{Id},名称:{GroupName}", entity.Id, entity.GroupName);
return entity.Id;
}
///
/// 更新人员组
///
[HttpPut]
public async Task UpdatePersonnelGroupAsync(PersonnelGroupUpdateInput input)
{
_logger.LogInformation("开始更新人员组,ID:{Id}", input.Id);
var entity = await _personnelGroupRepository.GetAsync(input.Id);
if (entity == null)
{
_logger.LogWarning("人员组不存在,ID:{Id}", input.Id);
throw new Exception($"人员组不存在,ID:{input.Id}");
}
// 业务验证:检查人员组名称是否已存在(排除自己)
var exists = await _personnelGroupRepository.ExistsGroupNameAsync(input.GroupName, input.Id);
if (exists)
{
_logger.LogWarning("人员组名称已存在:{GroupName}", input.GroupName);
throw new Exception($"人员组名称已存在:{input.GroupName}");
}
// 业务验证:人员组配置合法性检查
ValidatePersonnelGroupConfiguration(input);
// 更新实体属性
entity.GroupName = input.GroupName;
entity.Description = input.Description;
entity.GroupType = (int)input.GroupType;
entity.IsEnabled = input.IsEnabled;
entity.StaticPersonnelIds = JsonSerializer.Serialize(input.StaticPersonnelIds);
entity.DynamicDepartmentIds = JsonSerializer.Serialize(input.DynamicDepartmentIds);
entity.DynamicPositions = JsonSerializer.Serialize(input.DynamicPositions);
entity.OnlyActivePersonnel = input.OnlyActivePersonnel;
entity.ExcludePersonnelIds = JsonSerializer.Serialize(input.ExcludePersonnelIds);
entity.LastModifiedTime = DateTime.Now;
await _personnelGroupRepository.UpdateAsync(entity);
_logger.LogInformation("成功更新人员组,ID:{Id},名称:{GroupName}", entity.Id, entity.GroupName);
}
///
/// 删除人员组
///
[HttpDelete]
public async Task DeletePersonnelGroupAsync(long id)
{
_logger.LogInformation("开始删除人员组,ID:{Id}", id);
var entity = await _personnelGroupRepository.GetAsync(id);
if (entity == null)
{
_logger.LogWarning("人员组不存在,ID:{Id}", id);
throw new Exception($"人员组不存在,ID:{id}");
}
// 业务验证:检查是否存在关联的通知设置
var hasNotificationSettings = await _notificationSettingRepository.Select
.Where(a => a.PersonnelGroupId == id)
.AnyAsync();
if (hasNotificationSettings)
{
_logger.LogWarning("人员组存在关联的通知设置,无法删除,ID:{Id}", id);
throw new Exception($"人员组存在关联的通知设置,无法删除,ID:{id}");
}
await _personnelGroupRepository.DeleteAsync(id);
_logger.LogInformation("成功删除人员组,ID:{Id},名称:{GroupName}", id, entity.GroupName);
}
///
/// 获取人员组的实际人员列表
/// 根据决策点4:混合人员组,支持静态+动态规则
///
[HttpGet]
public async Task> GetPersonnelGroupMembersAsync(long personnelGroupId)
{
_logger.LogInformation("开始获取人员组实际人员列表,人员组ID:{PersonnelGroupId}", personnelGroupId);
var personnelGroup = await _personnelGroupRepository.GetAsync(personnelGroupId);
if (personnelGroup == null)
{
_logger.LogWarning("人员组不存在,ID:{PersonnelGroupId}", personnelGroupId);
throw new Exception($"人员组不存在,ID:{personnelGroupId}");
}
var allPersonnelIds = new HashSet();
// 获取静态人员
var staticPersonnelIds = JsonSerializer.Deserialize>(personnelGroup.StaticPersonnelIds);
if (staticPersonnelIds?.Any() == true)
{
foreach (var personnelId in staticPersonnelIds)
{
allPersonnelIds.Add(personnelId);
}
_logger.LogDebug("添加静态人员:{Count}个", staticPersonnelIds.Count);
}
// 获取动态人员(根据部门和职位规则)
var groupType = (PersonnelGroupTypeEnum)personnelGroup.GroupType;
if (groupType.HasFlag(PersonnelGroupTypeEnum.DynamicByDepartment) ||
groupType.HasFlag(PersonnelGroupTypeEnum.Mixed))
{
var dynamicPersonnelIds = await GetDynamicPersonnelIds(personnelGroup);
foreach (var personnelId in dynamicPersonnelIds)
{
allPersonnelIds.Add(personnelId);
}
_logger.LogDebug("添加动态人员:{Count}个", dynamicPersonnelIds.Count);
}
// 排除指定人员
var excludePersonnelIds = JsonSerializer.Deserialize>(personnelGroup.ExcludePersonnelIds);
if (excludePersonnelIds?.Any() == true)
{
foreach (var excludeId in excludePersonnelIds)
{
allPersonnelIds.Remove(excludeId);
}
_logger.LogDebug("排除人员:{Count}个", excludePersonnelIds.Count);
}
var result = allPersonnelIds.ToList();
_logger.LogInformation("成功获取人员组实际人员列表,人员组ID:{PersonnelGroupId},人员总数:{Count}", personnelGroupId, result.Count);
return result;
}
#endregion
#region 通知发送
///
/// 发送通知
/// 决策点1:支持邮件和系统消息通知
///
[HttpPost]
public async Task SendNotificationAsync(SendNotificationInput input)
{
_logger.LogInformation("开始发送通知,通知方式:{NotificationType},接收人数:{Count}",
input.NotificationType, input.RecipientPersonnelIds.Count);
var output = new SendNotificationOutput
{
TotalCount = input.RecipientPersonnelIds.Count,
SendTime = DateTime.Now
};
// 获取用户信息
var userInfoDict = await GetUserInfoDictionary(input.RecipientPersonnelIds);
// 逐个发送通知
foreach (var personnelId in input.RecipientPersonnelIds)
{
var sendResult = new NotificationSendResult
{
RecipientPersonnelId = personnelId,
NotificationType = input.NotificationType
};
try
{
if (userInfoDict.TryGetValue(personnelId, out var userInfo))
{
sendResult.RecipientPersonnelName = userInfo.Name;
sendResult.RecipientEmail = userInfo.Email;
// 创建通知历史记录
var historyId = await CreateNotificationHistory(input.SettingId, input, personnelId, userInfo);
sendResult.NotificationHistoryId = historyId;
// 发送通知
bool success = await SendSingleNotification(input, userInfo);
if (success)
{
sendResult.SendStatus = NotificationStatusEnum.Success;
sendResult.SendResult = "发送成功";
sendResult.SendTime = DateTime.Now;
output.SuccessCount++;
// 更新历史记录状态
await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Success, "发送成功", null);
}
else
{
sendResult.SendStatus = NotificationStatusEnum.Failed;
sendResult.ErrorMessage = "发送失败";
output.FailedCount++;
// 更新历史记录状态
await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Failed, null, "发送失败");
}
}
else
{
sendResult.SendStatus = NotificationStatusEnum.Failed;
sendResult.ErrorMessage = "用户不存在";
output.FailedCount++;
_logger.LogWarning("用户不存在,人员ID:{PersonnelId}", personnelId);
}
}
catch (Exception ex)
{
sendResult.SendStatus = NotificationStatusEnum.Failed;
sendResult.ErrorMessage = ex.Message;
output.FailedCount++;
_logger.LogError(ex, "发送通知异常,人员ID:{PersonnelId}", personnelId);
// 更新历史记录状态
if (sendResult.NotificationHistoryId > 0)
{
await UpdateNotificationHistoryStatus(sendResult.NotificationHistoryId,
NotificationStatusEnum.Failed, null, ex.Message);
}
}
output.SendResults.Add(sendResult);
output.NotificationHistoryIds.Add(sendResult.NotificationHistoryId);
}
output.IsAllSuccess = output.FailedCount == 0;
if (output.FailedCount > 0)
{
output.OverallErrorMessage = $"部分发送失败,失败数量:{output.FailedCount}";
}
_logger.LogInformation("完成发送通知,总数:{Total},成功:{Success},失败:{Failed}",
output.TotalCount, output.SuccessCount, output.FailedCount);
return output;
}
///
/// 发送群组通知(邮件发送一封给所有人,系统消息仍然单独发送)
///
[HttpPost]
public async Task SendGroupNotificationAsync(SendNotificationInput input)
{
_logger.LogInformation("开始发送群组通知,通知方式:{NotificationType},接收人数:{Count}",
input.NotificationType, input.RecipientPersonnelIds.Count);
var output = new SendNotificationOutput
{
TotalCount = input.RecipientPersonnelIds.Count,
SendTime = DateTime.Now
};
// 获取用户信息
var userInfoDict = await GetUserInfoDictionary(input.RecipientPersonnelIds);
// 过滤出有效的用户信息
var validUsers = new List<(long personnelId, UserInfo userInfo)>();
foreach (var personnelId in input.RecipientPersonnelIds)
{
if (userInfoDict.TryGetValue(personnelId, out var userInfo))
{
validUsers.Add((personnelId, userInfo));
}
else
{
// 处理无效用户
var sendResult = new NotificationSendResult
{
RecipientPersonnelId = personnelId,
NotificationType = input.NotificationType,
SendStatus = NotificationStatusEnum.Failed,
ErrorMessage = "用户不存在"
};
output.SendResults.Add(sendResult);
output.FailedCount++;
_logger.LogWarning("用户不存在,人员ID:{PersonnelId}", personnelId);
}
}
if (!validUsers.Any())
{
output.IsAllSuccess = false;
output.OverallErrorMessage = "没有有效的接收人";
return output;
}
try
{
if (input.NotificationType == NotificationTypeEnum.Email)
{
// 邮件通知:发送一封邮件给所有人
await SendGroupEmailNotification(input, validUsers, output);
}
else if (input.NotificationType == NotificationTypeEnum.SystemMessage)
{
// 系统消息:仍然逐个发送
await SendIndividualSystemMessages(input, validUsers, output);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "发送群组通知异常");
// 将所有结果标记为失败
foreach (var (personnelId, userInfo) in validUsers)
{
if (!output.SendResults.Any(r => r.RecipientPersonnelId == personnelId))
{
var sendResult = new NotificationSendResult
{
RecipientPersonnelId = personnelId,
RecipientPersonnelName = userInfo.Name,
RecipientEmail = userInfo.Email,
NotificationType = input.NotificationType,
SendStatus = NotificationStatusEnum.Failed,
ErrorMessage = ex.Message
};
output.SendResults.Add(sendResult);
output.FailedCount++;
}
}
}
output.IsAllSuccess = output.FailedCount == 0;
if (output.FailedCount > 0)
{
output.OverallErrorMessage = $"部分发送失败,失败数量:{output.FailedCount}";
}
_logger.LogInformation("完成发送群组通知,总数:{Total},成功:{Success},失败:{Failed}",
output.TotalCount, output.SuccessCount, output.FailedCount);
return output;
}
///
/// 批量发送通知
///
[HttpPost]
public async Task> BatchSendNotificationAsync(List inputs)
{
_logger.LogInformation("开始批量发送通知,批次数量:{Count}", inputs.Count);
var outputs = new List();
foreach (var input in inputs)
{
try
{
var output = await SendNotificationAsync(input);
outputs.Add(output);
}
catch (Exception ex)
{
_logger.LogError(ex, "批量发送通知异常,通知类型:{NotificationType}", input.NotificationType);
var errorOutput = new SendNotificationOutput
{
TotalCount = input.RecipientPersonnelIds.Count,
FailedCount = input.RecipientPersonnelIds.Count,
IsAllSuccess = false,
OverallErrorMessage = ex.Message,
SendTime = DateTime.Now
};
outputs.Add(errorOutput);
}
}
var totalSuccess = outputs.Sum(o => o.SuccessCount);
var totalFailed = outputs.Sum(o => o.FailedCount);
_logger.LogInformation("完成批量发送通知,批次数:{BatchCount},总成功:{Success},总失败:{Failed}",
outputs.Count, totalSuccess, totalFailed);
return outputs;
}
///
/// 根据通知设置发送通知
///
[HttpPost]
public async Task SendNotificationBySettingAsync(
long notificationSettingId,
string businessType,
long? businessId = null,
string businessData = "",
Dictionary templateVariables = null)
{
_logger.LogInformation("开始根据通知设置发送通知,设置ID:{SettingId},业务类型:{BusinessType}",
notificationSettingId, businessType);
// 获取通知设置
var notificationSetting = await _notificationSettingRepository.Select
.WhereDynamic(notificationSettingId)
.Include(a => a.PersonnelGroup)
.ToOneAsync();
if (notificationSetting == null)
{
_logger.LogWarning("通知设置不存在,ID:{SettingId}", notificationSettingId);
throw new Exception($"通知设置不存在,ID:{notificationSettingId}");
}
if (!notificationSetting.IsEnabled)
{
_logger.LogWarning("通知设置已禁用,ID:{SettingId}", notificationSettingId);
throw new Exception($"通知设置已禁用,ID:{notificationSettingId}");
}
return new SendNotificationOutput
{
IsAllSuccess = true,
OverallErrorMessage = "功能开发中",
SendTime = DateTime.Now
};
}
#endregion
#region 通知模板引擎(决策点7)
///
/// 验证模板语法
///
[HttpPost]
public async Task ValidateTemplateAsync(string template)
{
try
{
var result = await _templateService.ValidateTemplateAsync(new ValidateTemplateInput { Template = template });
return result.Success;
}
catch (Exception ex)
{
_logger.LogError(ex, "验证模板语法异常");
return false;
}
}
#endregion
#region 通知历史记录(决策点8)
///
/// 查询通知历史记录
///
[HttpGet]
public async Task GetNotificationHistoryAsync(long id)
{
_logger.LogInformation("开始查询通知历史记录,ID:{Id}", id);
var entity = await _notificationHistoryRepository.Select
.WhereDynamic(id)
.Include(a => a.NotificationSetting)
.ToOneAsync();
if (entity == null)
{
_logger.LogWarning("通知历史记录不存在,ID:{Id}", id);
throw new Exception($"通知历史记录不存在,ID:{id}");
}
var output = MapToNotificationHistoryOutput(entity);
_logger.LogInformation("成功查询通知历史记录,ID:{Id}", id);
return output;
}
///
/// 查询通知历史记录分页
///
[HttpPost]
public async Task> GetNotificationHistoryPageAsync(PageInput input)
{
_logger.LogInformation("开始查询通知历史记录分页,页码:{Current},页大小:{Size}", input.CurrentPage, input.PageSize);
var query = _notificationHistoryRepository.Select
.Include(a => a.NotificationSetting);
// 根据搜索条件过滤
if (input.Filter != null)
{
if (input.Filter.NotificationSettingId.HasValue && input.Filter.NotificationSettingId.Value > 0)
{
query = query.Where(a => a.NotificationSettingId == input.Filter.NotificationSettingId.Value);
}
if (input.Filter.RecipientPersonnelId.HasValue && input.Filter.RecipientPersonnelId.Value > 0)
{
query = query.Where(a => a.RecipientPersonnelId == input.Filter.RecipientPersonnelId.Value);
}
if (!string.IsNullOrEmpty(input.Filter.RecipientPersonnelName))
{
query = query.Where(a => a.RecipientPersonnelName.Contains(input.Filter.RecipientPersonnelName));
}
if (input.Filter.NotificationType.HasValue)
{
query = query.Where(a => a.NotificationType == (int)input.Filter.NotificationType.Value);
}
if (input.Filter.SendStatus.HasValue)
{
query = query.Where(a => a.SendStatus == (int)input.Filter.SendStatus.Value);
}
if (!string.IsNullOrEmpty(input.Filter.BusinessType))
{
query = query.Where(a => a.BusinessType.Contains(input.Filter.BusinessType));
}
if (input.Filter.StartTime.HasValue)
{
query = query.Where(a => a.CreatedTime >= input.Filter.StartTime.Value);
}
if (input.Filter.EndTime.HasValue)
{
query = query.Where(a => a.CreatedTime <= input.Filter.EndTime.Value);
}
}
var totalCount = await query.CountAsync();
var entities = await query
.OrderByDescending(a => a.CreatedTime)
.Page(input.CurrentPage, input.PageSize)
.ToListAsync();
var outputs = entities.Select(MapToNotificationHistoryOutput).ToList();
_logger.LogInformation("成功查询通知历史记录分页,总数:{Total},当前页数据:{Count}", totalCount, outputs.Count);
return new PageOutput
{
List = outputs,
Total = totalCount
};
}
///
/// 查询当前用户通知历史记录
///
[HttpPost]
public async Task> GetNotificationHistoryByUserPageAsync()
{
var query = _notificationHistoryRepository.Select
.Include(a => a.NotificationSetting);
query = query.Where(a => a.RecipientPersonnelId == User.Id && a.NotificationType == 2 && a.IsDeleted == false);
var totalCount = await query.CountAsync();
var entities = await query
.OrderByDescending(a => a.CreatedTime)
.Page(1, 10)
.ToListAsync();
var outputs = entities.Select(MapToNotificationHistoryOutput).ToList();
return new PageOutput
{
List = outputs,
Total = totalCount
};
}
///
/// 重试失败的通知
///
[HttpPost]
public async Task RetryFailedNotificationAsync(long notificationHistoryId)
{
_logger.LogInformation("开始重试失败的通知,历史记录ID:{HistoryId}", notificationHistoryId);
// 简化实现
await Task.Delay(100);
_logger.LogInformation("完成重试失败的通知,历史记录ID:{HistoryId}", notificationHistoryId);
return true;
}
///
/// 批量重试失败的通知
///
[HttpPost]
public async Task BatchRetryFailedNotificationsAsync(List notificationHistoryIds)
{
_logger.LogInformation("开始批量重试失败的通知,数量:{Count}", notificationHistoryIds.Count);
int successCount = 0;
foreach (var historyId in notificationHistoryIds)
{
try
{
bool success = await RetryFailedNotificationAsync(historyId);
if (success) successCount++;
}
catch (Exception ex)
{
_logger.LogError(ex, "批量重试失败通知异常,历史记录ID:{HistoryId}", historyId);
}
}
_logger.LogInformation("完成批量重试失败的通知,总数:{Total},成功:{Success}",
notificationHistoryIds.Count, successCount);
return successCount;
}
///
/// 取消通知
///
[HttpPost]
public async Task CancelNotificationAsync(long notificationHistoryId)
{
_logger.LogInformation("开始取消通知,历史记录ID:{HistoryId}", notificationHistoryId);
try
{
var history = await _notificationHistoryRepository.GetAsync(notificationHistoryId);
if (history == null)
{
_logger.LogWarning("通知历史记录不存在,ID:{HistoryId}", notificationHistoryId);
return false;
}
// 只有待发送状态的通知才能取消
if (history.SendStatus != (int)NotificationStatusEnum.Pending)
{
_logger.LogWarning("只有待发送状态的通知才能取消,当前状态:{Status},ID:{HistoryId}",
(NotificationStatusEnum)history.SendStatus, notificationHistoryId);
return false;
}
history.SendStatus = (int)NotificationStatusEnum.Cancelled;
history.SendResult = "通知已取消";
history.ActualSendTime = DateTime.Now;
await _notificationHistoryRepository.UpdateAsync(history);
_logger.LogInformation("成功取消通知,历史记录ID:{HistoryId}", notificationHistoryId);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "取消通知异常,历史记录ID:{HistoryId}", notificationHistoryId);
return false;
}
}
///
/// 批量取消通知
///
[HttpPost]
public async Task BatchCancelNotificationsAsync(List notificationHistoryIds)
{
_logger.LogInformation("开始批量取消通知,数量:{Count}", notificationHistoryIds.Count);
int successCount = 0;
foreach (var historyId in notificationHistoryIds)
{
try
{
bool success = await CancelNotificationAsync(historyId);
if (success) successCount++;
}
catch (Exception ex)
{
_logger.LogError(ex, "批量取消通知异常,历史记录ID:{HistoryId}", historyId);
}
}
_logger.LogInformation("完成批量取消通知,总数:{Total},成功:{Success}",
notificationHistoryIds.Count, successCount);
return successCount;
}
#endregion
#region 定时任务管理(决策点6)
///
/// 创建定时通知任务
///
[HttpPost]
public async Task CreateScheduledNotificationTaskAsync(
long notificationSettingId,
string businessType,
long? businessId = null,
string businessData = "",
DateTime? plannedExecutionTime = null,
string cronExpression = "")
{
_logger.LogInformation("开始创建定时通知任务,通知设置ID:{SettingId},业务类型:{BusinessType}",
notificationSettingId, businessType);
// 简化实现,返回模拟任务ID
var taskId = DateTime.Now.Ticks;
_logger.LogInformation("成功创建定时通知任务,任务ID:{TaskId}", taskId);
return taskId;
}
///
/// 执行定时通知任务
///
[HttpPost]
public async Task ExecuteScheduledNotificationTaskAsync(long taskId)
{
_logger.LogInformation("开始执行定时通知任务,任务ID:{TaskId}", taskId);
await Task.Delay(100);
_logger.LogInformation("成功执行定时通知任务,任务ID:{TaskId}", taskId);
return true;
}
///
/// 获取待执行的定时任务列表
///
[HttpGet]
public async Task> GetPendingNotificationTasksAsync()
{
await Task.CompletedTask;
return new List();
}
///
/// 启用/禁用定时任务
///
[HttpPut]
public async Task ToggleNotificationTaskAsync(long taskId, bool enabled)
{
_logger.LogInformation("开始{Action}定时任务,任务ID:{TaskId}", enabled ? "启用" : "禁用", taskId);
await Task.CompletedTask;
_logger.LogInformation("成功{Action}定时任务,任务ID:{TaskId}", enabled ? "启用" : "禁用", taskId);
}
#endregion
#region 通知统计
///
/// 获取通知发送统计信息
///
[HttpPost]
public async Task> GetNotificationStatisticsAsync(
DateTime startTime,
DateTime endTime,
long? notificationSettingId = null)
{
_logger.LogInformation("开始获取通知发送统计信息,时间范围:{StartTime} - {EndTime}", startTime, endTime);
var statistics = new Dictionary
{
["TotalCount"] = 0,
["SuccessCount"] = 0,
["FailedCount"] = 0,
["PendingCount"] = 0,
["SuccessRate"] = 0.0,
["EmailCount"] = 0,
["SystemMessageCount"] = 0,
["StatisticsTime"] = DateTime.Now
};
_logger.LogInformation("成功获取通知发送统计信息");
return statistics;
}
#endregion
#region 私有辅助方法
///
/// 用户信息DTO类
///
private class UserInfo
{
public long Id { get; set; }
public string Name { get; set; } = "";
public string Email { get; set; } = "";
}
///
/// 获取用户信息字典
///
private async Task> GetUserInfoDictionary(List personnelIds)
{
var userInfoDict = new Dictionary();
try
{
var cacheKey = CacheKeys.UserListKey;
var cacheOrgUsers = Cache.Get>(cacheKey);
if (cacheOrgUsers == null || (cacheOrgUsers != null && cacheOrgUsers.Count == 0))
{
cacheOrgUsers = await _userService.GetUserList();
Cache.Set(cacheKey, cacheOrgUsers, new TimeSpan(8, 0, 0));
}
foreach (var personnelId in personnelIds)
{
var cu = cacheOrgUsers.Where(x => x.Id == personnelId).FirstOrDefault();
userInfoDict[personnelId] = new UserInfo
{
Id = personnelId,
Name = cu?.Name,
Email = cu?.Email
};
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取用户信息异常,人员ID列表:{PersonnelIds}", string.Join(",", personnelIds));
}
return userInfoDict;
}
///
/// 发送单个通知
///
private async Task SendSingleNotification(SendNotificationInput input, UserInfo userInfo)
{
try
{
if (input.NotificationType == NotificationTypeEnum.Email)
{
return await SendEmailNotification(userInfo.Email, input.Title, input.Content);
}
else if (input.NotificationType == NotificationTypeEnum.SystemMessage)
{
return true;
}
return false;
}
catch (Exception ex)
{
_logger.LogError(ex, "发送单个通知异常,人员ID:{PersonnelId},通知方式:{NotificationType}",
userInfo.Id, input.NotificationType);
return false;
}
}
///
/// 发送群组邮件通知(一封邮件发送给所有人)
///
private async Task SendGroupEmailNotification(SendNotificationInput input,
List<(long personnelId, UserInfo userInfo)> validUsers, SendNotificationOutput output)
{
try
{
// 收集所有有效的邮箱地址
var emailAddresses = validUsers
.Where(u => !string.IsNullOrWhiteSpace(u.userInfo.Email))
.Select(u => u.userInfo.Email)
.Distinct()
.ToList();
if (!emailAddresses.Any())
{
// 没有有效邮箱,标记所有用户为失败
foreach (var (personnelId, userInfo) in validUsers)
{
var sendResult = new NotificationSendResult
{
RecipientPersonnelId = personnelId,
RecipientPersonnelName = userInfo.Name,
RecipientEmail = userInfo.Email,
NotificationType = input.NotificationType,
SendStatus = NotificationStatusEnum.Failed,
ErrorMessage = "邮箱地址无效"
};
output.SendResults.Add(sendResult);
output.FailedCount++;
}
return;
}
// 创建批量邮件发送请求
var batchEmailInput = new BatchSendEmailInput
{
Recipients = emailAddresses,
Subject = input.Title,
Content = input.Content,
IsHtml = true
};
// 发送批量邮件
var emailResult = await _emailNotificationService.BatchSendEmailAsync(batchEmailInput);
var sendTime = DateTime.Now;
// 为每个用户创建通知历史记录和发送结果
foreach (var (personnelId, userInfo) in validUsers)
{
try
{
// 创建通知历史记录
var historyId = await CreateNotificationHistory(input.SettingId, input, personnelId, userInfo);
// 判断该用户的邮件是否发送成功
var userEmailResult = emailResult.Results.FirstOrDefault(r => r.RecipientEmail == userInfo.Email);
var isSuccess = userEmailResult?.IsSuccess == true;
var sendResult = new NotificationSendResult
{
RecipientPersonnelId = personnelId,
RecipientPersonnelName = userInfo.Name,
RecipientEmail = userInfo.Email,
NotificationType = input.NotificationType,
NotificationHistoryId = historyId,
SendTime = sendTime
};
if (isSuccess)
{
sendResult.SendStatus = NotificationStatusEnum.Success;
sendResult.SendResult = "群组邮件发送成功";
output.SuccessCount++;
// 更新历史记录状态
await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Success, "群组邮件发送成功", null);
}
else
{
sendResult.SendStatus = NotificationStatusEnum.Failed;
sendResult.ErrorMessage = userEmailResult?.ErrorMessage ?? "群组邮件发送失败";
output.FailedCount++;
// 更新历史记录状态
await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Failed, null, sendResult.ErrorMessage);
}
output.SendResults.Add(sendResult);
output.NotificationHistoryIds.Add(historyId);
}
catch (Exception ex)
{
_logger.LogError(ex, "处理群组邮件发送结果异常,人员ID:{PersonnelId}", personnelId);
var sendResult = new NotificationSendResult
{
RecipientPersonnelId = personnelId,
RecipientPersonnelName = userInfo.Name,
RecipientEmail = userInfo.Email,
NotificationType = input.NotificationType,
SendStatus = NotificationStatusEnum.Failed,
ErrorMessage = ex.Message
};
output.SendResults.Add(sendResult);
output.FailedCount++;
}
}
_logger.LogInformation("群组邮件发送完成,邮箱数量:{EmailCount},用户数量:{UserCount}",
emailAddresses.Count, validUsers.Count);
}
catch (Exception ex)
{
_logger.LogError(ex, "发送群组邮件异常");
throw;
}
}
///
/// 发送个人系统消息(逐个发送)
///
private async Task SendIndividualSystemMessages(SendNotificationInput input,
List<(long personnelId, UserInfo userInfo)> validUsers, SendNotificationOutput output)
{
try
{
foreach (var (personnelId, userInfo) in validUsers)
{
var sendResult = new NotificationSendResult
{
RecipientPersonnelId = personnelId,
RecipientPersonnelName = userInfo.Name,
RecipientEmail = userInfo.Email,
NotificationType = input.NotificationType
};
try
{
// 创建通知历史记录
var historyId = await CreateNotificationHistory(input.SettingId, input, personnelId, userInfo);
sendResult.NotificationHistoryId = historyId;
// 发送系统消息
var success = await SendSystemMessageNotification(personnelId, input.Title, input.Content);
if (success)
{
sendResult.SendStatus = NotificationStatusEnum.Success;
sendResult.SendResult = "系统消息发送成功";
sendResult.SendTime = DateTime.Now;
output.SuccessCount++;
// 更新历史记录状态
await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Success, "系统消息发送成功", null);
}
else
{
sendResult.SendStatus = NotificationStatusEnum.Failed;
sendResult.ErrorMessage = "系统消息发送失败";
output.FailedCount++;
// 更新历史记录状态
await UpdateNotificationHistoryStatus(historyId, NotificationStatusEnum.Failed, null, "系统消息发送失败");
}
}
catch (Exception ex)
{
sendResult.SendStatus = NotificationStatusEnum.Failed;
sendResult.ErrorMessage = ex.Message;
output.FailedCount++;
_logger.LogError(ex, "发送系统消息异常,人员ID:{PersonnelId}", personnelId);
// 更新历史记录状态
if (sendResult.NotificationHistoryId > 0)
{
await UpdateNotificationHistoryStatus(sendResult.NotificationHistoryId,
NotificationStatusEnum.Failed, null, ex.Message);
}
}
output.SendResults.Add(sendResult);
output.NotificationHistoryIds.Add(sendResult.NotificationHistoryId);
}
_logger.LogInformation("个人系统消息发送完成,用户数量:{UserCount}", validUsers.Count);
}
catch (Exception ex)
{
_logger.LogError(ex, "发送个人系统消息异常");
throw;
}
}
///
/// 发送邮件通知
///
private async Task SendEmailNotification(string email, string title, string content)
{
try
{
var sendEmailInput = new SendEmailInput
{
RecipientEmail = email,
Subject = title,
Content = content
};
var result = await _emailNotificationService.SendEmailAsync(sendEmailInput);
return result.IsSuccess;
}
catch (Exception ex)
{
_logger.LogError(ex, "发送邮件通知异常,邮箱:{Email}", email);
return false;
}
}
///
/// 发送系统消息通知
///
private async Task SendSystemMessageNotification(long personnelId, string title, string content)
{
try
{
var sendMessageInput = new SendSystemMessageInput
{
RecipientPersonnelId = personnelId,
Title = title,
Content = content
};
var result = await _systemMessageService.SendSystemMessageAsync(sendMessageInput);
return result.Success;
}
catch (Exception ex)
{
_logger.LogError(ex, "发送系统消息异常,人员ID:{PersonnelId}", personnelId);
return false;
}
}
///
/// 创建通知历史记录
///
private async Task CreateNotificationHistory(long? notificationSettingId, SendNotificationInput input,
long personnelId, UserInfo userInfo)
{
try
{
var history = new NotificationHistoryEntity
{
NotificationSettingId = notificationSettingId ?? 0,
RecipientPersonnelId = personnelId,
RecipientPersonnelName = userInfo.Name,
RecipientEmail = userInfo.Email,
NotificationType = (int)input.NotificationType,
NotificationTitle = input.Title,
NotificationContent = input.Content,
PlannedSendTime = input.PlannedSendTime ?? DateTime.Now,
SendStatus = (int)NotificationStatusEnum.Pending,
MaxRetryCount = input.MaxRetryCount,
BusinessType = input.BusinessType,
BusinessId = input.BusinessId,
BusinessData = input.BusinessData
};
history = await _notificationHistoryRepository.InsertAsync(history);
return history.Id;
}
catch (Exception ex)
{
_logger.LogError(ex, "创建通知历史记录异常,人员ID:{PersonnelId}", personnelId);
return 0;
}
}
///
/// 更新通知历史记录状态
///
private async Task UpdateNotificationHistoryStatus(long historyId, NotificationStatusEnum status,
string sendResult, string errorMessage)
{
try
{
if (historyId <= 0) return;
var history = await _notificationHistoryRepository.GetAsync(historyId);
if (history != null)
{
history.SendStatus = (int)status;
history.SendResult = sendResult ?? "";
history.ErrorMessage = errorMessage ?? "";
if (status == NotificationStatusEnum.Success)
{
history.ActualSendTime = DateTime.Now;
}
await _notificationHistoryRepository.UpdateAsync(history);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "更新通知历史记录状态异常,历史记录ID:{HistoryId}", historyId);
}
}
///
/// 映射到NotificationSettingOutput
///
private NotificationSettingOutput MapToNotificationSettingOutput(NotificationSettingEntity entity)
{
return new NotificationSettingOutput
{
Id = entity.Id,
NotificationName = entity.NotificationName,
Description = entity.Description,
IsEnabled = entity.IsEnabled,
IsEmailEnabled = entity.IsEmailEnabled,
IsSystemMessageEnabled = entity.IsSystemMessageEnabled,
StartTime = entity.StartTime,
EndTime = entity.EndTime,
FrequencyType = (NotificationFrequencyEnum)entity.FrequencyType,
IntervalMinutes = entity.IntervalMinutes,
PersonnelGroupId = entity.PersonnelGroupId,
PersonnelGroupName = entity.PersonnelGroup?.GroupName ?? "",
EmailSubjectTemplate = entity.EmailSubjectTemplate,
EmailContentTemplate = entity.EmailContentTemplate,
SystemMessageTitleTemplate = entity.SystemMessageTitleTemplate,
SystemMessageContentTemplate = entity.SystemMessageContentTemplate,
TriggerConditions = entity.TriggerConditions,
CreatedTime = entity.CreatedTime ?? DateTime.MinValue,
ModifiedTime = entity.ModifiedTime,
LastModifiedTime = entity.LastModifiedTime
};
}
///
/// 映射到PersonnelGroupOutput
///
private PersonnelGroupOutput MapToPersonnelGroupOutput(PersonnelGroupEntity entity)
{
var staticPersonnelIds = JsonSerializer.Deserialize>(entity.StaticPersonnelIds) ?? new List();
var dynamicDepartmentIds = JsonSerializer.Deserialize>(entity.DynamicDepartmentIds) ?? new List();
var dynamicPositions = JsonSerializer.Deserialize>(entity.DynamicPositions) ?? new List();
var excludePersonnelIds = JsonSerializer.Deserialize>(entity.ExcludePersonnelIds) ?? new List();
return new PersonnelGroupOutput
{
Id = entity.Id,
GroupName = entity.GroupName,
Description = entity.Description,
GroupType = (PersonnelGroupTypeEnum)entity.GroupType,
IsEnabled = entity.IsEnabled,
StaticPersonnelIds = staticPersonnelIds,
DynamicDepartmentIds = dynamicDepartmentIds,
DynamicPositions = dynamicPositions,
OnlyActivePersonnel = entity.OnlyActivePersonnel,
ExcludePersonnelIds = excludePersonnelIds,
CreatedTime = entity.CreatedTime ?? DateTime.MinValue,
ModifiedTime = entity.ModifiedTime,
LastModifiedTime = entity.LastModifiedTime
};
}
///
/// 映射到NotificationHistoryOutput
///
private NotificationHistoryOutput MapToNotificationHistoryOutput(NotificationHistoryEntity entity)
{
return new NotificationHistoryOutput
{
Id = entity.Id,
NotificationSettingId = entity.NotificationSettingId,
NotificationSettingName = entity.NotificationSetting?.NotificationName ?? "",
RecipientPersonnelId = entity.RecipientPersonnelId,
RecipientPersonnelName = entity.RecipientPersonnelName,
RecipientEmail = entity.RecipientEmail,
NotificationType = (NotificationTypeEnum)entity.NotificationType,
NotificationTitle = entity.NotificationTitle,
NotificationContent = entity.NotificationContent,
PlannedSendTime = entity.PlannedSendTime,
ActualSendTime = entity.ActualSendTime,
SendStatus = (NotificationStatusEnum)entity.SendStatus,
SendResult = entity.SendResult,
ErrorMessage = entity.ErrorMessage,
RetryCount = entity.RetryCount,
MaxRetryCount = entity.MaxRetryCount,
NextRetryTime = entity.NextRetryTime,
BusinessType = entity.BusinessType,
BusinessId = entity.BusinessId,
BusinessData = entity.BusinessData,
CreatedTime = entity.CreatedTime ?? DateTime.MinValue
};
}
#endregion
#region 私有辅助方法验证
///
/// 验证时间配置合法性
///
private void ValidateTimeConfiguration(string startTime, string endTime)
{
if (!string.IsNullOrEmpty(startTime) && !string.IsNullOrEmpty(endTime))
{
if (TimeOnly.TryParse(startTime, out var start) && TimeOnly.TryParse(endTime, out var end))
{
if (start >= end)
{
throw new Exception("开始时间不能大于等于结束时间");
}
}
}
}
///
/// 验证频次配置合法性
///
private void ValidateFrequencyConfiguration(NotificationFrequencyEnum frequencyType, int? intervalMinutes)
{
if (frequencyType == NotificationFrequencyEnum.FixedInterval && (!intervalMinutes.HasValue || intervalMinutes.Value <= 0))
{
throw new Exception("间隔频次时,间隔分钟数必须大于0");
}
}
///
/// 验证模板配置合法性
///
private async Task ValidateTemplateConfiguration(dynamic input)
{
if (!string.IsNullOrEmpty(input.EmailSubjectTemplate))
{
var result = await _templateService.ValidateTemplateAsync(new ValidateTemplateInput { Template = input.EmailSubjectTemplate });
if (!result.Success)
{
throw new Exception($"邮件主题模板格式错误:{result.ErrorMessage}");
}
}
}
///
/// 验证人员组配置合法性
///
private void ValidatePersonnelGroupConfiguration(PersonnelGroupCreateInput input)
{
var groupType = (PersonnelGroupTypeEnum)input.GroupType;
if (groupType == PersonnelGroupTypeEnum.Static && (input.StaticPersonnelIds == null || !input.StaticPersonnelIds.Any()))
{
throw new Exception("静态人员组必须配置人员");
}
if ((groupType == PersonnelGroupTypeEnum.DynamicByDepartment || groupType == PersonnelGroupTypeEnum.Mixed) &&
(input.DynamicDepartmentIds == null || !input.DynamicDepartmentIds.Any()))
{
throw new Exception("动态部门人员组必须配置部门");
}
}
///
/// 获取动态人员ID列表
///
private async Task> GetDynamicPersonnelIds(PersonnelGroupEntity personnelGroup)
{
var orgUserIds = new List();
var dynamicDepartmentIds = JsonSerializer.Deserialize>(personnelGroup.DynamicDepartmentIds);
foreach (var orgId in dynamicDepartmentIds)
{
var cacheKey = CacheKeys.GetDynamicDepartmentKey(orgId);
var cacheOrgUserIds = Cache.Get>(cacheKey);
if (cacheOrgUserIds != null && cacheOrgUserIds.Any())
{
orgUserIds.AddRange(cacheOrgUserIds.Select(m => m.Id).ToList());
}
else
{
var orgUsers = await _userService.GetOrgUserList(orgId);
Cache.Set(cacheKey, orgUsers, new TimeSpan(8, 0, 0));
orgUserIds.AddRange(orgUsers.Select(m => m.Id).ToList());
}
}
return orgUserIds;
}
#endregion
}