feat(mail): 增强邮件模板参数解析和内容格式化功能

This commit is contained in:
YunaiV
2025-12-25 09:59:34 +08:00
parent e6dcbde8a7
commit 315a024ccc
2 changed files with 35 additions and 43 deletions

View File

@@ -131,52 +131,47 @@ public class MailTemplateServiceImpl implements MailTemplateService {
@Override @Override
public String formatMailTemplateContent(String content, Map<String, Object> params) { public String formatMailTemplateContent(String content, Map<String, Object> params) {
// 先替换模板变量 // 1. 先替换模板变量
String formattedContent = StrUtil.format(content, params); String formattedContent = StrUtil.format(content, params);
// 反转义HTML特殊字符 // 关联 Pull Requesthttps://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1461 讨论
// 2.1 反转义HTML特殊字符
formattedContent = unescapeHtml(formattedContent); formattedContent = unescapeHtml(formattedContent);
// 2.2 处理代码块(确保<pre><code>标签格式正确)
// 处理代码块(确保<pre><code>标签格式正确)
formattedContent = formatHtmlCodeBlocks(formattedContent); formattedContent = formatHtmlCodeBlocks(formattedContent);
// 2.3 将最外层的 pre 标签替换为 div 标签
// 将最外层的pre标签替换为div标签
formattedContent = replaceOuterPreWithDiv(formattedContent); formattedContent = replaceOuterPreWithDiv(formattedContent);
return formattedContent; return formattedContent;
} }
private String replaceOuterPreWithDiv(String content) { private String replaceOuterPreWithDiv(String content) {
if (content == null) { if (StrUtil.isEmpty(content)) {
return null; return content;
} }
// 使用正则表达式匹配所有的 <pre> 标签,包括嵌套的 <code> 标签
// 使用正则表达式匹配所有的<pre>标签,包括嵌套的<code>标签
String regex = "(?s)<pre[^>]*>(.*?)</pre>"; String regex = "(?s)<pre[^>]*>(.*?)</pre>";
Pattern pattern = Pattern.compile(regex); Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content); Matcher matcher = pattern.matcher(content);
StringBuilder sb = new StringBuilder();
StringBuffer sb = new StringBuffer();
while (matcher.find()) { while (matcher.find()) {
// 提取<pre>标签内的内容 // 提取 <pre> 标签内的内容
String innerContent = matcher.group(1); String innerContent = matcher.group(1);
// 返回div标签包裹的内容 // 返回 div 标签包裹的内容
matcher.appendReplacement(sb, "<div>" + innerContent + "</div>"); matcher.appendReplacement(sb, "<div>" + innerContent + "</div>");
} }
matcher.appendTail(sb); matcher.appendTail(sb);
return sb.toString(); return sb.toString();
} }
/** /**
* 反转义HTML特殊字符 * 反转义 HTML 特殊字符
* *
* @param input 输入字符串 * @param input 输入字符串
* @return 反转义后的字符串 * @return 反转义后的字符串
*/ */
private String unescapeHtml(String input) { private String unescapeHtml(String input) {
if (input == null) { if (StrUtil.isEmpty(input)) {
return null; return input;
} }
return input return input
.replace("&amp;", "&") .replace("&amp;", "&")
@@ -188,27 +183,24 @@ public class MailTemplateServiceImpl implements MailTemplateService {
} }
/** /**
* 格式化HTML中的代码块 * 格式化 HTML 中的代码块
* *
* @param content 邮件内容 * @param content 邮件内容
* @return 格式化后的邮件内容 * @return 格式化后的邮件内容
*/ */
private String formatHtmlCodeBlocks(String content) { private String formatHtmlCodeBlocks(String content) {
// 匹配<pre><code>标签的代码块 // 匹配 <pre><code> 标签的代码块
Pattern codeBlockPattern = Pattern.compile("<pre\\s*.*?><code\\s*.*?>(.*?)</code></pre>", Pattern.DOTALL); Pattern codeBlockPattern = Pattern.compile("<pre\\s*.*?><code\\s*.*?>(.*?)</code></pre>", Pattern.DOTALL);
Matcher matcher = codeBlockPattern.matcher(content); Matcher matcher = codeBlockPattern.matcher(content);
StringBuilder sb = new StringBuilder();
StringBuffer sb = new StringBuffer();
while (matcher.find()) { while (matcher.find()) {
// 获取代码块内容 // 获取代码块内容
String codeBlock = matcher.group(1); String codeBlock = matcher.group(1);
// 为代码块添加样式 // 为代码块添加样式
String replacement = "<pre style=\"background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto;\"><code>" + codeBlock + "</code></pre>"; String replacement = "<pre style=\"background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto;\"><code>" + codeBlock + "</code></pre>";
matcher.appendReplacement(sb, replacement); matcher.appendReplacement(sb, replacement);
} }
matcher.appendTail(sb); matcher.appendTail(sb);
return sb.toString(); return sb.toString();
} }
@@ -216,6 +208,7 @@ public class MailTemplateServiceImpl implements MailTemplateService {
public long getMailTemplateCountByAccountId(Long accountId) { public long getMailTemplateCountByAccountId(Long accountId) {
return mailTemplateMapper.selectCountByAccountId(accountId); return mailTemplateMapper.selectCountByAccountId(accountId);
} }
/** /**
* 解析标题和内容中的参数 * 解析标题和内容中的参数
*/ */
@@ -223,7 +216,6 @@ public class MailTemplateServiceImpl implements MailTemplateService {
public List<String> parseTemplateTitleAndContentParams(String title, String content) { public List<String> parseTemplateTitleAndContentParams(String title, String content) {
List<String> titleParams = ReUtil.findAllGroup1(PATTERN_PARAMS, title); List<String> titleParams = ReUtil.findAllGroup1(PATTERN_PARAMS, title);
List<String> contentParams = ReUtil.findAllGroup1(PATTERN_PARAMS, content); List<String> contentParams = ReUtil.findAllGroup1(PATTERN_PARAMS, content);
// 合并参数并去重 // 合并参数并去重
List<String> allParams = new ArrayList<>(titleParams); List<String> allParams = new ArrayList<>(titleParams);
for (String param : contentParams) { for (String param : contentParams) {