using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
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;
namespace NPP.SmartSchedue.Api.Services.Notification;
///
/// 通知服务 模板
///
[DynamicApi(Area = "app")]
public class NotificationTemplateService : BaseService, INotificationTemplateService, IDynamicApi
{
// 变量匹配正则表达式:匹配 {变量名} 格式
private static readonly Regex VariableRegex = new Regex(@"\{([a-zA-Z_][a-zA-Z0-9_]*)\}", RegexOptions.Compiled);
#region 模板渲染
///
/// 渲染通知模板
/// 支持变量替换,如:{变量名}
///
/// 渲染模板输入参数
/// 渲染结果
[HttpPost]
public async Task RenderTemplateAsync(RenderTemplateInput input)
{
try
{
var renderedContent = RenderTemplateCore(input.Template, input.Variables);
return await Task.FromResult(new RenderTemplateOutput
{
RenderedContent = renderedContent,
Success = true
});
}
catch (Exception ex)
{
return new RenderTemplateOutput
{
Success = false,
ErrorMessage = $"渲染模板时发生错误:{ex.Message}"
};
}
}
#endregion
#region 模板验证
///
/// 验证模板语法是否正确
///
/// 验证模板输入参数
/// 验证结果
[HttpPost]
public async Task ValidateTemplateAsync(ValidateTemplateInput input)
{
try
{
var validationResult = ValidateTemplateCore(input.Template);
return await Task.FromResult(new ValidateTemplateOutput
{
ValidationResult = validationResult,
Success = true
});
}
catch (Exception ex)
{
return new ValidateTemplateOutput
{
Success = false,
ErrorMessage = $"验证模板时发生错误:{ex.Message}",
ValidationResult = new TemplateValidationResult()
};
}
}
#endregion
#region 变量解析
///
/// 提取模板中的变量列表
///
/// 提取变量输入参数
/// 变量列表
[HttpPost]
public async Task ExtractVariablesAsync(ExtractVariablesInput input)
{
try
{
var variables = ExtractVariablesCore(input.Template);
return await Task.FromResult(new ExtractVariablesOutput
{
Variables = variables,
Success = true
});
}
catch (Exception ex)
{
return new ExtractVariablesOutput
{
Success = false,
ErrorMessage = $"提取变量时发生错误:{ex.Message}"
};
}
}
#endregion
#region 内置变量
///
/// 获取系统内置变量
///
/// 系统变量字典
[HttpPost]
public async Task GetSystemVariablesAsync()
{
try
{
var systemVariables = GetSystemVariablesCore();
return await Task.FromResult(new GetSystemVariablesOutput
{
Variables = systemVariables,
Success = true
});
}
catch (Exception ex)
{
return new GetSystemVariablesOutput
{
Success = false,
ErrorMessage = $"获取系统变量时发生错误:{ex.Message}"
};
}
}
///
/// 获取业务相关变量
///
/// 获取业务变量输入参数
/// 业务变量字典
[HttpPost]
public async Task GetBusinessVariablesAsync(GetBusinessVariablesInput input)
{
try
{
var businessVariables = await GetBusinessVariablesCore(input.BusinessType, input.BusinessId, input.BusinessData);
return new GetBusinessVariablesOutput
{
Variables = businessVariables,
Success = true
};
}
catch (Exception ex)
{
return new GetBusinessVariablesOutput
{
Success = false,
ErrorMessage = $"获取业务变量时发生错误:{ex.Message}"
};
}
}
#endregion
#region 模板预定义
///
/// 获取预定义模板列表
///
/// 获取模板列表输入参数
/// 预定义模板列表
[HttpPost]
public async Task GetPredefinedTemplatesAsync(GetPredefinedTemplatesInput input)
{
try
{
var templates = GetDefaultPredefinedTemplates();
if (!string.IsNullOrWhiteSpace(input.Category))
{
templates = templates.Where(t =>
string.Equals(t.Category, input.Category, StringComparison.OrdinalIgnoreCase)).ToList();
}
return await Task.FromResult(new GetPredefinedTemplatesOutput
{
Templates = templates,
TotalCount = templates.Count,
Success = true
});
}
catch (Exception ex)
{
return new GetPredefinedTemplatesOutput
{
Success = false,
ErrorMessage = $"获取预定义模板列表时发生错误:{ex.Message}"
};
}
}
///
/// 获取指定预定义模板
///
/// 获取指定模板输入参数
/// 预定义模板
[HttpPost]
public async Task GetPredefinedTemplateAsync(GetPredefinedTemplateInput input)
{
try
{
var templates = GetDefaultPredefinedTemplates();
var template = templates.FirstOrDefault(t =>
string.Equals(t.TemplateId, input.TemplateId, StringComparison.OrdinalIgnoreCase));
return await Task.FromResult(new GetPredefinedTemplateOutput
{
Template = template,
Success = true
});
}
catch (Exception ex)
{
return new GetPredefinedTemplateOutput
{
Success = false,
ErrorMessage = $"获取指定预定义模板时发生错误:{ex.Message}"
};
}
}
#endregion
#region 核心业务逻辑方法
///
/// 核心模板渲染逻辑
///
/// 模板内容
/// 变量字典
/// 渲染后的内容
private string RenderTemplateCore(string template, Dictionary variables)
{
if (string.IsNullOrWhiteSpace(template))
return string.Empty;
if (variables == null || !variables.Any())
return template;
var result = template;
// 替换所有匹配的变量
result = VariableRegex.Replace(result, match =>
{
var variableName = match.Groups[1].Value;
// 如果变量存在于字典中,则替换
if (variables.TryGetValue(variableName, out var variableValue))
{
return variableValue ?? string.Empty;
}
// 如果变量不存在,保留原始占位符
return match.Value;
});
return result;
}
///
/// 核心模板验证逻辑
///
/// 模板内容
/// 验证结果
private TemplateValidationResult ValidateTemplateCore(string template)
{
var result = new TemplateValidationResult();
if (string.IsNullOrWhiteSpace(template))
{
result.AddError("模板内容不能为空");
return result;
}
try
{
// 提取所有变量
var variables = ExtractVariablesCore(template);
result.Variables = variables;
// 检查变量命名规范
foreach (var variable in variables)
{
if (!IsValidVariableName(variable))
{
result.AddError($"变量名 '{variable}' 不符合命名规范,变量名只能包含字母、数字和下划线,且不能以数字开头");
}
}
// 检查是否有未闭合的大括号
var openBraceCount = template.Count(c => c == '{');
var closeBraceCount = template.Count(c => c == '}');
if (openBraceCount != closeBraceCount)
{
result.AddError($"大括号不匹配:找到 {openBraceCount} 个左大括号和 {closeBraceCount} 个右大括号");
}
// 检查嵌套大括号
if (template.Contains("{{") || template.Contains("}}"))
{
result.AddWarning("发现嵌套大括号,这可能导致变量替换异常");
}
// 检查空的变量占位符
if (template.Contains("{}"))
{
result.AddError("发现空的变量占位符 {},请指定变量名");
}
}
catch (Exception ex)
{
result.AddError($"模板验证时发生异常:{ex.Message}");
}
return result;
}
///
/// 核心变量提取逻辑
///
/// 模板内容
/// 变量名列表
private List ExtractVariablesCore(string template)
{
if (string.IsNullOrWhiteSpace(template))
return new List();
var variables = new HashSet();
var matches = VariableRegex.Matches(template);
foreach (Match match in matches)
{
var variableName = match.Groups[1].Value;
variables.Add(variableName);
}
return variables.OrderBy(v => v).ToList();
}
///
/// 获取系统内置变量核心逻辑
///
/// 系统变量字典
private Dictionary GetSystemVariablesCore()
{
var now = DateTime.Now;
return new Dictionary
{
["CurrentDateTime"] = now.ToString("yyyy-MM-dd HH:mm:ss"),
["CurrentDate"] = now.ToString("yyyy-MM-dd"),
["CurrentTime"] = now.ToString("HH:mm:ss"),
["CurrentYear"] = now.Year.ToString(),
["CurrentMonth"] = now.Month.ToString(),
["CurrentDay"] = now.Day.ToString(),
["CurrentWeekday"] = GetWeekdayName(now.DayOfWeek),
["SystemName"] = "NPP智能生产调度系统",
["CompanyName"] = "核电站"
};
}
///
/// 获取业务相关变量核心逻辑
///
/// 业务类型
/// 业务ID
/// 业务数据
/// 业务变量字典
private async Task> GetBusinessVariablesCore(
string businessType,
long? businessId,
string businessData)
{
var businessVariables = new Dictionary
{
["BusinessType"] = businessType ?? "",
["BusinessId"] = businessId?.ToString() ?? ""
};
// 根据业务类型添加特定变量
switch (businessType?.ToLower())
{
case "workorder":
case "工作任务":
await AddWorkOrderVariablesAsync(businessVariables, businessId, businessData);
break;
case "equipment":
case "设备":
await AddEquipmentVariablesAsync(businessVariables, businessId, businessData);
break;
case "personnel":
case "人员":
await AddPersonnelVariablesAsync(businessVariables, businessId, businessData);
break;
case "maintenance":
case "维护":
await AddMaintenanceVariablesAsync(businessVariables, businessId, businessData);
break;
}
return businessVariables;
}
#endregion
#region 私有辅助方法
///
/// 验证变量名是否符合规范
///
/// 变量名
/// 是否符合规范
private static bool IsValidVariableName(string variableName)
{
if (string.IsNullOrWhiteSpace(variableName))
return false;
// 变量名只能包含字母、数字和下划线,且不能以数字开头
return Regex.IsMatch(variableName, @"^[a-zA-Z_][a-zA-Z0-9_]*$");
}
///
/// 获取星期几的中文名称
///
/// 星期枚举
/// 中文名称
private static string GetWeekdayName(DayOfWeek dayOfWeek)
{
return dayOfWeek switch
{
DayOfWeek.Monday => "星期一",
DayOfWeek.Tuesday => "星期二",
DayOfWeek.Wednesday => "星期三",
DayOfWeek.Thursday => "星期四",
DayOfWeek.Friday => "星期五",
DayOfWeek.Saturday => "星期六",
DayOfWeek.Sunday => "星期日",
_ => ""
};
}
///
/// 添加工作任务相关变量
///
/// 变量字典
/// 业务ID
/// 业务数据
/// 异步任务
private async Task AddWorkOrderVariablesAsync(Dictionary variables, long? businessId, string businessData)
{
// 这里可以根据businessId查询工作任务详情,然后添加相关变量
// 为了简化示例,先添加一些基础变量
variables["WorkOrderId"] = businessId?.ToString() ?? "";
if (!string.IsNullOrWhiteSpace(businessData))
{
try
{
var data = JsonConvert.DeserializeObject>(businessData);
if (data != null)
{
foreach (var item in data)
{
variables[$"WorkOrder_{item.Key}"] = item.Value?.ToString() ?? "";
}
}
}
catch (JsonException)
{
// 忽略JSON解析错误
}
}
await Task.CompletedTask;
}
///
/// 添加设备相关变量
///
/// 变量字典
/// 业务ID
/// 业务数据
/// 异步任务
private async Task AddEquipmentVariablesAsync(Dictionary variables, long? businessId, string businessData)
{
variables["EquipmentId"] = businessId?.ToString() ?? "";
// 可以添加更多设备相关变量
await Task.CompletedTask;
}
///
/// 添加人员相关变量
///
/// 变量字典
/// 业务ID
/// 业务数据
/// 异步任务
private async Task AddPersonnelVariablesAsync(Dictionary variables, long? businessId, string businessData)
{
variables["PersonnelId"] = businessId?.ToString() ?? "";
// 可以添加更多人员相关变量
await Task.CompletedTask;
}
///
/// 添加维护相关变量
///
/// 变量字典
/// 业务ID
/// 业务数据
/// 异步任务
private async Task AddMaintenanceVariablesAsync(Dictionary variables, long? businessId, string businessData)
{
variables["MaintenanceId"] = businessId?.ToString() ?? "";
// 可以添加更多维护相关变量
await Task.CompletedTask;
}
///
/// 获取默认预定义模板
///
/// 预定义模板列表
private static List GetDefaultPredefinedTemplates()
{
return new List
{
new PredefinedTemplate
{
TemplateId = "work_order_assignment",
TemplateName = "工作任务分配通知",
Category = "工作任务",
Description = "当工作任务被分配给人员时发送的通知",
EmailSubjectTemplate = "工作任务分配通知 - {WorkOrderCode}",
EmailContentTemplate = @"
工作任务分配通知
您好,{PersonnelName}!
有新的工作任务分配给您:
- 任务代码:{WorkOrderCode}
- 项目号:{ProjectNumber}
- 工序名称:{ProcessName}
- 计划开始时间:{PlannedStartTime}
- 计划结束时间:{PlannedEndTime}
请及时查看并开始执行任务。
系统时间:{CurrentDateTime}
",
SystemMessageTitleTemplate = "新任务分配 - {WorkOrderCode}",
SystemMessageContentTemplate = "您有新的工作任务:{WorkOrderCode},请及时处理。",
SupportedVariables = new List
{
new TemplateVariable { Name = "PersonnelName", Description = "人员姓名", IsRequired = true },
new TemplateVariable { Name = "WorkOrderCode", Description = "任务代码", IsRequired = true },
new TemplateVariable { Name = "ProjectNumber", Description = "项目号", IsRequired = true },
new TemplateVariable { Name = "ProcessName", Description = "工序名称", IsRequired = true },
new TemplateVariable { Name = "PlannedStartTime", Description = "计划开始时间", IsRequired = true },
new TemplateVariable { Name = "PlannedEndTime", Description = "计划结束时间", IsRequired = true }
}
},
new PredefinedTemplate
{
TemplateId = "equipment_maintenance_reminder",
TemplateName = "设备维护提醒",
Category = "设备维护",
Description = "设备维护到期提醒通知",
EmailSubjectTemplate = "设备维护提醒 - {EquipmentName}",
EmailContentTemplate = @"
设备维护提醒
您好,{PersonnelName}!
以下设备需要进行维护:
- 设备名称:{EquipmentName}
- 设备编号:{EquipmentCode}
- 计划维护时间:{PlannedMaintenanceTime}
- 维护类型:{MaintenanceType}
请及时安排维护工作。
系统时间:{CurrentDateTime}
",
SystemMessageTitleTemplate = "设备维护提醒 - {EquipmentName}",
SystemMessageContentTemplate = "设备 {EquipmentName} 需要维护,计划时间:{PlannedMaintenanceTime}",
SupportedVariables = new List
{
new TemplateVariable { Name = "PersonnelName", Description = "人员姓名", IsRequired = true },
new TemplateVariable { Name = "EquipmentName", Description = "设备名称", IsRequired = true },
new TemplateVariable { Name = "EquipmentCode", Description = "设备编号", IsRequired = true },
new TemplateVariable { Name = "PlannedMaintenanceTime", Description = "计划维护时间", IsRequired = true },
new TemplateVariable { Name = "MaintenanceType", Description = "维护类型", IsRequired = false }
}
}
};
}
#endregion
}