Commit 315a024ccc465597a9e6aa57a3fec6e2339c4338
1 parent
e6dcbde8
feat(mail): 增强邮件模板参数解析和内容格式化功能
Showing
2 changed files
with
35 additions
and
43 deletions
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImpl.java
| @@ -131,52 +131,47 @@ public class MailTemplateServiceImpl implements MailTemplateService { | @@ -131,52 +131,47 @@ public class MailTemplateServiceImpl implements MailTemplateService { | ||
| 131 | 131 | ||
| 132 | @Override | 132 | @Override |
| 133 | public String formatMailTemplateContent(String content, Map<String, Object> params) { | 133 | public String formatMailTemplateContent(String content, Map<String, Object> params) { |
| 134 | - // 先替换模板变量 | 134 | + // 1. 先替换模板变量 |
| 135 | String formattedContent = StrUtil.format(content, params); | 135 | String formattedContent = StrUtil.format(content, params); |
| 136 | 136 | ||
| 137 | - // 反转义HTML特殊字符 | 137 | + // 关联 Pull Request:https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1461 讨论 |
| 138 | + // 2.1 反转义HTML特殊字符 | ||
| 138 | formattedContent = unescapeHtml(formattedContent); | 139 | formattedContent = unescapeHtml(formattedContent); |
| 139 | - | ||
| 140 | - // 处理代码块(确保<pre><code>标签格式正确) | 140 | + // 2.2 处理代码块(确保<pre><code>标签格式正确) |
| 141 | formattedContent = formatHtmlCodeBlocks(formattedContent); | 141 | formattedContent = formatHtmlCodeBlocks(formattedContent); |
| 142 | - | ||
| 143 | - // 将最外层的pre标签替换为div标签 | 142 | + // 2.3 将最外层的 pre 标签替换为 div 标签 |
| 144 | formattedContent = replaceOuterPreWithDiv(formattedContent); | 143 | formattedContent = replaceOuterPreWithDiv(formattedContent); |
| 145 | - | ||
| 146 | return formattedContent; | 144 | return formattedContent; |
| 147 | } | 145 | } |
| 148 | 146 | ||
| 149 | private String replaceOuterPreWithDiv(String content) { | 147 | private String replaceOuterPreWithDiv(String content) { |
| 150 | - if (content == null) { | ||
| 151 | - return null; | 148 | + if (StrUtil.isEmpty(content)) { |
| 149 | + return content; | ||
| 152 | } | 150 | } |
| 153 | - | ||
| 154 | - // 使用正则表达式匹配所有的<pre>标签,包括嵌套的<code>标签 | 151 | + // 使用正则表达式匹配所有的 <pre> 标签,包括嵌套的 <code> 标签 |
| 155 | String regex = "(?s)<pre[^>]*>(.*?)</pre>"; | 152 | String regex = "(?s)<pre[^>]*>(.*?)</pre>"; |
| 156 | Pattern pattern = Pattern.compile(regex); | 153 | Pattern pattern = Pattern.compile(regex); |
| 157 | Matcher matcher = pattern.matcher(content); | 154 | Matcher matcher = pattern.matcher(content); |
| 158 | - | ||
| 159 | - StringBuffer sb = new StringBuffer(); | 155 | + StringBuilder sb = new StringBuilder(); |
| 160 | while (matcher.find()) { | 156 | while (matcher.find()) { |
| 161 | - // 提取<pre>标签内的内容 | 157 | + // 提取 <pre> 标签内的内容 |
| 162 | String innerContent = matcher.group(1); | 158 | String innerContent = matcher.group(1); |
| 163 | - // 返回div标签包裹的内容 | 159 | + // 返回 div 标签包裹的内容 |
| 164 | matcher.appendReplacement(sb, "<div>" + innerContent + "</div>"); | 160 | matcher.appendReplacement(sb, "<div>" + innerContent + "</div>"); |
| 165 | } | 161 | } |
| 166 | matcher.appendTail(sb); | 162 | matcher.appendTail(sb); |
| 167 | - | ||
| 168 | return sb.toString(); | 163 | return sb.toString(); |
| 169 | } | 164 | } |
| 170 | 165 | ||
| 171 | /** | 166 | /** |
| 172 | - * 反转义HTML特殊字符 | 167 | + * 反转义 HTML 特殊字符 |
| 173 | * | 168 | * |
| 174 | * @param input 输入字符串 | 169 | * @param input 输入字符串 |
| 175 | * @return 反转义后的字符串 | 170 | * @return 反转义后的字符串 |
| 176 | */ | 171 | */ |
| 177 | private String unescapeHtml(String input) { | 172 | private String unescapeHtml(String input) { |
| 178 | - if (input == null) { | ||
| 179 | - return null; | 173 | + if (StrUtil.isEmpty(input)) { |
| 174 | + return input; | ||
| 180 | } | 175 | } |
| 181 | return input | 176 | return input |
| 182 | .replace("&", "&") | 177 | .replace("&", "&") |
| @@ -188,27 +183,24 @@ public class MailTemplateServiceImpl implements MailTemplateService { | @@ -188,27 +183,24 @@ public class MailTemplateServiceImpl implements MailTemplateService { | ||
| 188 | } | 183 | } |
| 189 | 184 | ||
| 190 | /** | 185 | /** |
| 191 | - * 格式化HTML中的代码块 | 186 | + * 格式化 HTML 中的代码块 |
| 192 | * | 187 | * |
| 193 | * @param content 邮件内容 | 188 | * @param content 邮件内容 |
| 194 | * @return 格式化后的邮件内容 | 189 | * @return 格式化后的邮件内容 |
| 195 | */ | 190 | */ |
| 196 | private String formatHtmlCodeBlocks(String content) { | 191 | private String formatHtmlCodeBlocks(String content) { |
| 197 | - // 匹配<pre><code>标签的代码块 | 192 | + // 匹配 <pre><code> 标签的代码块 |
| 198 | Pattern codeBlockPattern = Pattern.compile("<pre\\s*.*?><code\\s*.*?>(.*?)</code></pre>", Pattern.DOTALL); | 193 | Pattern codeBlockPattern = Pattern.compile("<pre\\s*.*?><code\\s*.*?>(.*?)</code></pre>", Pattern.DOTALL); |
| 199 | Matcher matcher = codeBlockPattern.matcher(content); | 194 | Matcher matcher = codeBlockPattern.matcher(content); |
| 200 | - | ||
| 201 | - StringBuffer sb = new StringBuffer(); | 195 | + StringBuilder sb = new StringBuilder(); |
| 202 | while (matcher.find()) { | 196 | while (matcher.find()) { |
| 203 | // 获取代码块内容 | 197 | // 获取代码块内容 |
| 204 | String codeBlock = matcher.group(1); | 198 | String codeBlock = matcher.group(1); |
| 205 | - | ||
| 206 | // 为代码块添加样式 | 199 | // 为代码块添加样式 |
| 207 | String replacement = "<pre style=\"background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto;\"><code>" + codeBlock + "</code></pre>"; | 200 | String replacement = "<pre style=\"background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto;\"><code>" + codeBlock + "</code></pre>"; |
| 208 | matcher.appendReplacement(sb, replacement); | 201 | matcher.appendReplacement(sb, replacement); |
| 209 | } | 202 | } |
| 210 | matcher.appendTail(sb); | 203 | matcher.appendTail(sb); |
| 211 | - | ||
| 212 | return sb.toString(); | 204 | return sb.toString(); |
| 213 | } | 205 | } |
| 214 | 206 | ||
| @@ -216,6 +208,7 @@ public class MailTemplateServiceImpl implements MailTemplateService { | @@ -216,6 +208,7 @@ public class MailTemplateServiceImpl implements MailTemplateService { | ||
| 216 | public long getMailTemplateCountByAccountId(Long accountId) { | 208 | public long getMailTemplateCountByAccountId(Long accountId) { |
| 217 | return mailTemplateMapper.selectCountByAccountId(accountId); | 209 | return mailTemplateMapper.selectCountByAccountId(accountId); |
| 218 | } | 210 | } |
| 211 | + | ||
| 219 | /** | 212 | /** |
| 220 | * 解析标题和内容中的参数 | 213 | * 解析标题和内容中的参数 |
| 221 | */ | 214 | */ |
| @@ -223,7 +216,6 @@ public class MailTemplateServiceImpl implements MailTemplateService { | @@ -223,7 +216,6 @@ public class MailTemplateServiceImpl implements MailTemplateService { | ||
| 223 | public List<String> parseTemplateTitleAndContentParams(String title, String content) { | 216 | public List<String> parseTemplateTitleAndContentParams(String title, String content) { |
| 224 | List<String> titleParams = ReUtil.findAllGroup1(PATTERN_PARAMS, title); | 217 | List<String> titleParams = ReUtil.findAllGroup1(PATTERN_PARAMS, title); |
| 225 | List<String> contentParams = ReUtil.findAllGroup1(PATTERN_PARAMS, content); | 218 | List<String> contentParams = ReUtil.findAllGroup1(PATTERN_PARAMS, content); |
| 226 | - | ||
| 227 | // 合并参数并去重 | 219 | // 合并参数并去重 |
| 228 | List<String> allParams = new ArrayList<>(titleParams); | 220 | List<String> allParams = new ArrayList<>(titleParams); |
| 229 | for (String param : contentParams) { | 221 | for (String param : contentParams) { |
yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java
| @@ -221,7 +221,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -221,7 +221,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 221 | 221 | ||
| 222 | // 调用,并断言结果 | 222 | // 调用,并断言结果 |
| 223 | String result = mailTemplateService.formatMailTemplateContent(content, params); | 223 | String result = mailTemplateService.formatMailTemplateContent(content, params); |
| 224 | - // 断言pre标签被替换为div标签 | 224 | + // 断言 pre 标签被替换为 div 标签 |
| 225 | assertTrue(result.contains("<div><code>public class Test {")); | 225 | assertTrue(result.contains("<div><code>public class Test {")); |
| 226 | assertTrue(result.contains("System.out.println(\"Hello 测试\"")); | 226 | assertTrue(result.contains("System.out.println(\"Hello 测试\"")); |
| 227 | assertTrue(result.contains("</code></div>")); | 227 | assertTrue(result.contains("</code></div>")); |
| @@ -233,10 +233,10 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -233,10 +233,10 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 233 | Map<String, Object> params = new HashMap<>(); | 233 | Map<String, Object> params = new HashMap<>(); |
| 234 | params.put("content", "测试内容"); | 234 | params.put("content", "测试内容"); |
| 235 | 235 | ||
| 236 | - // 测试pre标签替换为div标签 | 236 | + // 测试 pre 标签替换为 div 标签 |
| 237 | String content = "<pre><code>{content}</code></pre>"; | 237 | String content = "<pre><code>{content}</code></pre>"; |
| 238 | String result = mailTemplateService.formatMailTemplateContent(content, params); | 238 | String result = mailTemplateService.formatMailTemplateContent(content, params); |
| 239 | - // 断言结果中包含div标签,而不包含pre标签 | 239 | + // 断言结果中包含 div 标签,而不包含 pre 标签 |
| 240 | assertTrue(result.contains("<div><code>测试内容</code></div>")); | 240 | assertTrue(result.contains("<div><code>测试内容</code></div>")); |
| 241 | } | 241 | } |
| 242 | 242 | ||
| @@ -247,7 +247,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -247,7 +247,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 247 | params.put("username", "testuser"); | 247 | params.put("username", "testuser"); |
| 248 | params.put("company", "测试公司"); | 248 | params.put("company", "测试公司"); |
| 249 | 249 | ||
| 250 | - // 测试完整的HTML邮件模板 | 250 | + // 测试完整的 HTML 邮件模板 |
| 251 | String content = "<!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n <meta charset=\"UTF-8\">\n <title>Title</title>\n </head>\n <body>\n <div>\n <includetail>\n <div>\n <div class=\"open_email\" style=\"margin: 8px; \">\n <div>\n <br>\n <span class=\"genEmailContent\">\n <div id=\"cTMail-Wrap\" style=\"word-break: break-all;box-sizing:border-box;text-align:left;min-width:320px; max-width:660px; border:1px solid #f6f6f6; background-color:#f7f8fa; margin:auto; padding:20px 0 30px; font-family:'helvetica neue',PingFangSC-Light,arial,'hiragino sans gb','microsoft yahei ui','microsoft yahei',simsun,sans-serif\">\n <div class=\"main-content\">\n <table style=\"width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse\">\n <tbody>\n <tr style=\"font-weight:300\">\n <td style=\"width:3%;max-width:30px;\"></td>\n <td style=\"max-width:600px;\">\n <div id=\"cTMail-logo\" style=\"width:92px; height:36px;\">\n <a href=\"\">\n <img border=\"0\" src=\"左上角图片logo\" style=\"width:120px; height:36px;display:block\">\n </a>\n </div>\n <div style=\"color: #C2C5C9;width: 260px;float: right;font-size: 12px;\">此邮件由系统发出,请勿直接回复或转发他人</div>\n <p style=\"height:2px;background-color: #00a4ff;border: 0;font-size:0;padding:0;width:100%;margin-top:20px;\"></p>\n <div id=\"cTMail-inner\" style=\"background-color:#fff; padding:23px 0 20px;box-shadow: 0px 1px 1px 0px rgba(122, 55, 55, 0.2);text-align:left;\">\n <table style=\"width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse;\">\n <tbody>\n <tr style=\"font-weight:300\">\n <td style=\"width:3.2%;max-width:30px;\"></td>\n <td style=\"max-width:480px;\">\n <h1 id=\"cTMail-title\" style=\"font-size: 20px; line-height: 36px; margin: 0px 0px 22px;\">\n 尊敬的 {username},\n </h1>\n <dl style=\"font-size: 14px; color: #595E65; line-height: 18px;\">\n <dd style=\"margin: 0px 0px 6px; padding: 0px; font-size: 14px; line-height: 22px;\">\n <p id=\"cTMail-sender\" style=\"font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;\">\n 内容<br>\n 内容<br>\n 内容123<br><br>\n\n 如果您在使用过程中遇到任何问题或者有任何建议,都可以随时联系我们的客户团队,我们将竭诚为您服务。\n\n\n\n\n <br>\n <br>\n {company}<br>\n 地址:xxxxx<br>\n 邮箱:lambc77@163.com\n </p>\n </dd>\n </dl>\n <hr style=\"border: 0.1px solid #e5e5e5;\"/>\n <dl style=\"font-size: 14px; color: #595E65; line-height: 18px;\">\n <div style=\"color: #93979B;\">\n <strong>声明:本邮件含有保密信息,仅限于收件人所用。禁止任何人未经发件人许可,以任何形式(包括但不限于部分的泄露、复制或散发)不当的使用本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件,谢谢!\n </strong><br>\n </div>\n </dl>\n </td>\n <td style=\"width:3.2%;max-width:30px;\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n </td>\n <td style=\"width:3%;max-width:30px;\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </span>\n </div>\n </div>\n </div>\n </includetail>\n </div>\n </body>\n <script>\n\n </script>\n </html>"; | 251 | String content = "<!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n <meta charset=\"UTF-8\">\n <title>Title</title>\n </head>\n <body>\n <div>\n <includetail>\n <div>\n <div class=\"open_email\" style=\"margin: 8px; \">\n <div>\n <br>\n <span class=\"genEmailContent\">\n <div id=\"cTMail-Wrap\" style=\"word-break: break-all;box-sizing:border-box;text-align:left;min-width:320px; max-width:660px; border:1px solid #f6f6f6; background-color:#f7f8fa; margin:auto; padding:20px 0 30px; font-family:'helvetica neue',PingFangSC-Light,arial,'hiragino sans gb','microsoft yahei ui','microsoft yahei',simsun,sans-serif\">\n <div class=\"main-content\">\n <table style=\"width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse\">\n <tbody>\n <tr style=\"font-weight:300\">\n <td style=\"width:3%;max-width:30px;\"></td>\n <td style=\"max-width:600px;\">\n <div id=\"cTMail-logo\" style=\"width:92px; height:36px;\">\n <a href=\"\">\n <img border=\"0\" src=\"左上角图片logo\" style=\"width:120px; height:36px;display:block\">\n </a>\n </div>\n <div style=\"color: #C2C5C9;width: 260px;float: right;font-size: 12px;\">此邮件由系统发出,请勿直接回复或转发他人</div>\n <p style=\"height:2px;background-color: #00a4ff;border: 0;font-size:0;padding:0;width:100%;margin-top:20px;\"></p>\n <div id=\"cTMail-inner\" style=\"background-color:#fff; padding:23px 0 20px;box-shadow: 0px 1px 1px 0px rgba(122, 55, 55, 0.2);text-align:left;\">\n <table style=\"width:100%;font-weight:300;margin-bottom:10px;border-collapse:collapse;\">\n <tbody>\n <tr style=\"font-weight:300\">\n <td style=\"width:3.2%;max-width:30px;\"></td>\n <td style=\"max-width:480px;\">\n <h1 id=\"cTMail-title\" style=\"font-size: 20px; line-height: 36px; margin: 0px 0px 22px;\">\n 尊敬的 {username},\n </h1>\n <dl style=\"font-size: 14px; color: #595E65; line-height: 18px;\">\n <dd style=\"margin: 0px 0px 6px; padding: 0px; font-size: 14px; line-height: 22px;\">\n <p id=\"cTMail-sender\" style=\"font-size: 14px; line-height: 26px; word-wrap: break-word; word-break: break-all; margin-top: 32px;\">\n 内容<br>\n 内容<br>\n 内容123<br><br>\n\n 如果您在使用过程中遇到任何问题或者有任何建议,都可以随时联系我们的客户团队,我们将竭诚为您服务。\n\n\n\n\n <br>\n <br>\n {company}<br>\n 地址:xxxxx<br>\n 邮箱:lambc77@163.com\n </p>\n </dd>\n </dl>\n <hr style=\"border: 0.1px solid #e5e5e5;\"/>\n <dl style=\"font-size: 14px; color: #595E65; line-height: 18px;\">\n <div style=\"color: #93979B;\">\n <strong>声明:本邮件含有保密信息,仅限于收件人所用。禁止任何人未经发件人许可,以任何形式(包括但不限于部分的泄露、复制或散发)不当的使用本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件,谢谢!\n </strong><br>\n </div>\n </dl>\n </td>\n <td style=\"width:3.2%;max-width:30px;\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n </td>\n <td style=\"width:3%;max-width:30px;\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </span>\n </div>\n </div>\n </div>\n </includetail>\n </div>\n </body>\n <script>\n\n </script>\n </html>"; |
| 252 | 252 | ||
| 253 | // 调用,并断言成功处理 | 253 | // 调用,并断言成功处理 |
| @@ -255,7 +255,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -255,7 +255,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 255 | // 断言结果中包含替换后的变量 | 255 | // 断言结果中包含替换后的变量 |
| 256 | assertTrue(result.contains("尊敬的 testuser")); | 256 | assertTrue(result.contains("尊敬的 testuser")); |
| 257 | assertTrue(result.contains("测试公司")); | 257 | assertTrue(result.contains("测试公司")); |
| 258 | - // 断言结果是有效的HTML | 258 | + // 断言结果是有效的 HTML |
| 259 | assertTrue(result.startsWith("<!DOCTYPE html>")); | 259 | assertTrue(result.startsWith("<!DOCTYPE html>")); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| @@ -287,7 +287,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -287,7 +287,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 287 | params.put("param1", "value1"); | 287 | params.put("param1", "value1"); |
| 288 | params.put("param2", "value2"); | 288 | params.put("param2", "value2"); |
| 289 | 289 | ||
| 290 | - // 测试多个pre标签的情况 | 290 | + // 测试多个 pre 标签的情况 |
| 291 | String content = "<pre><code>First code block: {param1}</code></pre>\n" + | 291 | String content = "<pre><code>First code block: {param1}</code></pre>\n" + |
| 292 | "<p>Some text between code blocks</p>\n" + | 292 | "<p>Some text between code blocks</p>\n" + |
| 293 | "<pre><code>Second code block: {param2}</code></pre>"; | 293 | "<pre><code>Second code block: {param2}</code></pre>"; |
| @@ -302,7 +302,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -302,7 +302,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 302 | // 准备参数 | 302 | // 准备参数 |
| 303 | Map<String, Object> params = new HashMap<>(); | 303 | Map<String, Object> params = new HashMap<>(); |
| 304 | 304 | ||
| 305 | - // 简化测试,只测试基本的HTML特殊字符 | 305 | + // 简化测试,只测试基本的 HTML 特殊字符 |
| 306 | String content = "<div>测试 & 特殊字符</div>"; | 306 | String content = "<div>测试 & 特殊字符</div>"; |
| 307 | String result = mailTemplateService.formatMailTemplateContent(content, params); | 307 | String result = mailTemplateService.formatMailTemplateContent(content, params); |
| 308 | // 断言特殊字符被正确反转义 | 308 | // 断言特殊字符被正确反转义 |
| @@ -327,7 +327,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -327,7 +327,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 327 | 327 | ||
| 328 | @Test | 328 | @Test |
| 329 | public void testDifferenceWithHtmlContent() { | 329 | public void testDifferenceWithHtmlContent() { |
| 330 | - // 准备包含HTML格式的模板内容 | 330 | + // 准备包含 HTML 格式的模板内容 |
| 331 | String content = "<div style='font-family: Arial, sans-serif; color: #333;'>" + | 331 | String content = "<div style='font-family: Arial, sans-serif; color: #333;'>" + |
| 332 | "<h1>Welcome, {username}!</h1>" + | 332 | "<h1>Welcome, {username}!</h1>" + |
| 333 | "<p>Your account has been created successfully.</p>" + | 333 | "<p>Your account has been created successfully.</p>" + |
| @@ -347,28 +347,28 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | @@ -347,28 +347,28 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 347 | params.put("role", "admin"); | 347 | params.put("role", "admin"); |
| 348 | params.put("activationLink", "https://example.com/activate?code=12345"); | 348 | params.put("activationLink", "https://example.com/activate?code=12345"); |
| 349 | 349 | ||
| 350 | - // 1. 使用parseTemplateContentParams:只提取参数名称,忽略了HTML格式 | 350 | + // 1. 使用 parseTemplateContentParams:只提取参数名称,忽略了 HTML 格式 |
| 351 | List<String> parsedParams = mailTemplateService.parseTemplateContentParams(content); | 351 | List<String> parsedParams = mailTemplateService.parseTemplateContentParams(content); |
| 352 | System.out.println("parseTemplateContentParams结果:" + parsedParams); | 352 | System.out.println("parseTemplateContentParams结果:" + parsedParams); |
| 353 | 353 | ||
| 354 | - // 断言:只提取了纯参数名称,没有HTML格式 | 354 | + // 断言:只提取了纯参数名称,没有 HTML 格式 |
| 355 | assertEquals(6, parsedParams.size()); | 355 | assertEquals(6, parsedParams.size()); |
| 356 | // 检查所有参数类型 | 356 | // 检查所有参数类型 |
| 357 | - assertTrue(parsedParams.stream().filter("username"::equals).count() == 3); | ||
| 358 | - assertTrue(parsedParams.stream().filter("email"::equals).count() == 1); | ||
| 359 | - assertTrue(parsedParams.stream().filter("role"::equals).count() == 1); | ||
| 360 | - assertTrue(parsedParams.stream().filter("activationLink"::equals).count() == 1); | ||
| 361 | - // 断言:没有包含任何HTML标签 | 357 | + assertEquals(3, parsedParams.stream().filter("username"::equals).count()); |
| 358 | + assertEquals(1, parsedParams.stream().filter("email"::equals).count()); | ||
| 359 | + assertEquals(1, parsedParams.stream().filter("role"::equals).count()); | ||
| 360 | + assertEquals(1, parsedParams.stream().filter("activationLink"::equals).count()); | ||
| 361 | + // 断言:没有包含任何 HTML 标签 | ||
| 362 | for (String param : parsedParams) { | 362 | for (String param : parsedParams) { |
| 363 | assertFalse(param.contains("<")); | 363 | assertFalse(param.contains("<")); |
| 364 | assertFalse(param.contains(">")); | 364 | assertFalse(param.contains(">")); |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | - // 2. 使用formatMailTemplateContent:处理HTML格式,生成最终内容 | 367 | + // 2. 使用 formatMailTemplateContent:处理 HTML 格式,生成最终内容 |
| 368 | String formattedContent = mailTemplateService.formatMailTemplateContent(content, params); | 368 | String formattedContent = mailTemplateService.formatMailTemplateContent(content, params); |
| 369 | System.out.println("formatMailTemplateContent结果:" + formattedContent); | 369 | System.out.println("formatMailTemplateContent结果:" + formattedContent); |
| 370 | 370 | ||
| 371 | - // 断言:HTML格式被保留并处理 | 371 | + // 断言:HTML 格式被保留并处理 |
| 372 | assertTrue(formattedContent.contains("<div style='font-family: Arial, sans-serif; color: #333;'>")); | 372 | assertTrue(formattedContent.contains("<div style='font-family: Arial, sans-serif; color: #333;'>")); |
| 373 | assertTrue(formattedContent.contains("<h1>Welcome, testuser!</h1>")); | 373 | assertTrue(formattedContent.contains("<h1>Welcome, testuser!</h1>")); |
| 374 | assertTrue(formattedContent.contains("<a href='https://example.com/activate?code=12345'>here</a>")); | 374 | assertTrue(formattedContent.contains("<a href='https://example.com/activate?code=12345'>here</a>")); |