Browse Source

feat: update mail template (#62)

master
vran 3 years ago
committed by GitHub
parent
commit
492b1cd5d9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      build.gradle
  2. 2
      core/build.gradle
  3. 3
      core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java
  4. 60
      core/src/main/java/com/databasir/core/infrastructure/event/subscriber/DocumentEventSubscriber.java
  5. 43
      core/src/main/java/com/databasir/core/infrastructure/event/subscriber/UserEventSubscriber.java
  6. 36
      core/src/main/java/com/databasir/core/infrastructure/mail/MailSender.java
  7. 22
      core/src/main/java/com/databasir/core/infrastructure/mail/MailTemplateConfig.java
  8. 30
      core/src/main/java/com/databasir/core/infrastructure/mail/MailTemplateProcessor.java
  9. 0
      core/src/main/resources/ftl/mail/DiscussCreated.ftl
  10. 81
      core/src/main/resources/ftl/mail/DocumentUpdated.ftl
  11. 61
      core/src/main/resources/ftl/mail/PasswordRenew.ftl
  12. 65
      core/src/main/resources/ftl/mail/UserCreated.ftl

2
build.gradle

@ -35,6 +35,7 @@ subprojects {
hikariVersion = '5.0.0' hikariVersion = '5.0.0'
jacksonVersion = '2.13.1' jacksonVersion = '2.13.1'
easyExcelVersion = '3.0.5' easyExcelVersion = '3.0.5'
freemarkerVersion = '2.3.31'
} }
dependencies { dependencies {
@ -49,6 +50,7 @@ subprojects {
implementation "org.slf4j:slf4j-api:${slf4jVersion}" implementation "org.slf4j:slf4j-api:${slf4jVersion}"
implementation "com.alibaba:easyexcel:${easyExcelVersion}" implementation "com.alibaba:easyexcel:${easyExcelVersion}"
implementation "org.freemarker:freemarker:${freemarkerVersion}"
} }

2
core/build.gradle

@ -29,8 +29,8 @@ dependencies {
// others // others
implementation 'com.auth0:java-jwt:3.18.3' implementation 'com.auth0:java-jwt:3.18.3'
implementation 'org.commonmark:commonmark:0.18.1' implementation 'org.commonmark:commonmark:0.18.1'
implementation 'org.freemarker:freemarker:2.3.31'
implementation 'com.alibaba:easyexcel' implementation 'com.alibaba:easyexcel'
implementation "org.freemarker:freemarker"
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0' implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'

3
core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java

@ -112,7 +112,8 @@ public class DocumentService {
eventPublisher.publish(new DocumentUpdated(diff, version + 1, version, projectId)); eventPublisher.publish(new DocumentUpdated(diff, version + 1, version, projectId));
} else { } else {
saveNewDocument(current, 1L, projectId); saveNewDocument(current, 1L, projectId);
eventPublisher.publish(new DocumentUpdated(null, 1L, null, projectId)); RootDiff diff = Diffs.diff(null, current);
eventPublisher.publish(new DocumentUpdated(diff, 1L, null, projectId));
} }
} }

60
core/src/main/java/com/databasir/core/infrastructure/event/subscriber/DocumentEventSubscriber.java

@ -4,6 +4,7 @@ import com.databasir.core.diff.data.DiffType;
import com.databasir.core.diff.data.RootDiff; import com.databasir.core.diff.data.RootDiff;
import com.databasir.core.domain.document.event.DocumentUpdated; import com.databasir.core.domain.document.event.DocumentUpdated;
import com.databasir.core.infrastructure.mail.MailSender; import com.databasir.core.infrastructure.mail.MailSender;
import com.databasir.core.infrastructure.mail.MailTemplateProcessor;
import com.databasir.dao.impl.ProjectDao; import com.databasir.dao.impl.ProjectDao;
import com.databasir.dao.impl.SysMailDao; import com.databasir.dao.impl.SysMailDao;
import com.databasir.dao.impl.UserDao; import com.databasir.dao.impl.UserDao;
@ -14,7 +15,10 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component @Component
@ -30,26 +34,33 @@ public class DocumentEventSubscriber {
private final SysMailDao sysMailDao; private final SysMailDao sysMailDao;
private final MailTemplateProcessor mailTemplateProcessor;
@EventListener(classes = DocumentUpdated.class) @EventListener(classes = DocumentUpdated.class)
public void onDocumentUpdated(DocumentUpdated created) { public void onDocumentUpdated(DocumentUpdated created) {
ProjectPojo project = projectDao.selectById(created.getProjectId());
List<String> to = userDao.selectEnabledGroupMembers(project.getGroupId())
.stream()
.map(UserPojo::getEmail)
.filter(mail -> mail.contains("@"))
.collect(Collectors.toList());
sysMailDao.selectOptionTopOne().ifPresent(mail -> { sysMailDao.selectOptionTopOne().ifPresent(mail -> {
String subject = project.getName() + " 文档有新的版本"; ProjectPojo project = projectDao.selectById(created.getProjectId());
String message = created.getDiff() List<String> to = userDao.selectEnabledGroupMembers(project.getGroupId())
.map(diff -> build(diff)) .stream()
.orElseGet(() -> "首次文档同步常规"); .filter(UserPojo::getEnabled)
mailSender.batchSend(mail, to, subject, message); .map(UserPojo::getEmail)
.filter(userEmail -> userEmail.contains("@"))
.collect(Collectors.toList());
String subject = project.getName() + " 文档有新的内容变更";
List<Map<String, String>> diffs = created.getDiff()
.map(this::diffs)
.orElseGet(Collections::emptyList);
Map<String, Object> context = new HashMap<>();
context.put("diffs", diffs);
context.put("projectName", project.getName());
String message = mailTemplateProcessor.process("ftl/mail/DocumentUpdated.ftl", context);
mailSender.batchSendHtml(mail, to, subject, message);
}); });
} }
private String build(RootDiff diff) { private List<Map<String, String>> diffs(RootDiff diff) {
if (diff.getDiffType() == DiffType.NONE) { if (diff.getDiffType() == DiffType.NONE) {
return ""; return Collections.emptyList();
} else { } else {
return diff.getFields() return diff.getFields()
.stream() .stream()
@ -57,25 +68,14 @@ public class DocumentEventSubscriber {
.flatMap(f -> f.getFields().stream()) .flatMap(f -> f.getFields().stream())
.map(table -> { .map(table -> {
String tableName = table.getFieldName(); String tableName = table.getFieldName();
String change = toDescription(table.getDiffType()); Map<String, String> map = Map.of(
return tableName + " " + change; "tableName", tableName,
"diffType", table.getDiffType().name()
);
return map;
}) })
.collect(Collectors.joining("\n")); .collect(Collectors.toList());
} }
} }
private String toDescription(DiffType diffType) {
switch (diffType) {
case NONE:
return "无变化";
case ADDED:
return "新增";
case REMOVED:
return "删除";
case MODIFIED:
return "修改";
default:
return diffType.name();
}
}
} }

43
core/src/main/java/com/databasir/core/infrastructure/event/subscriber/UserEventSubscriber.java

@ -4,6 +4,7 @@ import com.databasir.core.domain.user.data.UserSource;
import com.databasir.core.domain.user.event.UserCreated; import com.databasir.core.domain.user.event.UserCreated;
import com.databasir.core.domain.user.event.UserPasswordRenewed; import com.databasir.core.domain.user.event.UserPasswordRenewed;
import com.databasir.core.infrastructure.mail.MailSender; import com.databasir.core.infrastructure.mail.MailSender;
import com.databasir.core.infrastructure.mail.MailTemplateProcessor;
import com.databasir.dao.impl.SysMailDao; import com.databasir.dao.impl.SysMailDao;
import com.databasir.dao.impl.UserDao; import com.databasir.dao.impl.UserDao;
import com.databasir.dao.tables.pojos.UserPojo; import com.databasir.dao.tables.pojos.UserPojo;
@ -12,6 +13,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/** /**
* TODO use html template instead of simple message * TODO use html template instead of simple message
*/ */
@ -26,36 +30,41 @@ public class UserEventSubscriber {
private final UserDao userDao; private final UserDao userDao;
private final MailTemplateProcessor mailTemplateProcessor;
@EventListener(classes = UserPasswordRenewed.class) @EventListener(classes = UserPasswordRenewed.class)
public void onPasswordRenewed(UserPasswordRenewed event) { public void onPasswordRenewed(UserPasswordRenewed event) {
UserPojo operator = userDao.selectById(event.getRenewByUserId()); UserPojo operator = userDao.selectById(event.getRenewByUserId());
sysMailDao.selectOptionTopOne() sysMailDao.selectOptionTopOne()
.ifPresent(mailPojo -> { .ifPresent(mailPojo -> {
String renewBy = operator.getNickname(); String renewBy = operator.getNickname();
String subject = "Databasir 密码重置提醒"; Map<String, Object> context = new HashMap<>();
String message = String.format("Hi %s,\r\n 您的密码已被 %s 重置,新密码为 %s", context.put("renewBy", renewBy);
event.getNickname(), context.put("nickname", event.getNickname());
renewBy, context.put("newPassword", event.getNewPassword());
event.getNewPassword()); String message = template("ftl/mail/PasswordRenew.ftl", context);
mailSender.send(mailPojo, event.getEmail(), subject, message); String subject = "Databasir 密码重置通知";
mailSender.sendHtml(mailPojo, event.getEmail(), subject, message);
}); });
} }
@EventListener(classes = UserCreated.class) @EventListener(classes = UserCreated.class)
public void onUserCreated(UserCreated event) { public void onUserCreated(UserCreated event) {
String subject = "Databasir 账户创建成功";
String message;
if (UserSource.isManual(event.getSource())) { if (UserSource.isManual(event.getSource())) {
message = String.format("Hi %s\r\n您的 Databasir 账户已创建成功,用户名:%s,密码:%s", sysMailDao.selectOptionTopOne()
event.getNickname(), event.getUsername(), event.getRawPassword()); .ifPresent(mailPojo -> {
} else { Map<String, Object> context = new HashMap<>();
message = String.format("Hi %s\r\n您的 Databasir 账户已创建成功,用户名:%s", context.put("nickname", event.getNickname());
event.getNickname(), event.getUsername()); context.put("username", event.getUsername());
context.put("password", event.getRawPassword());
String message = template("ftl/mail/UserCreated.ftl", context);
String subject = "Databasir 账户创建成功";
mailSender.sendHtml(mailPojo, event.getEmail(), subject, message);
});
} }
sysMailDao.selectOptionTopOne()
.ifPresent(mailPojo -> {
mailSender.send(mailPojo, event.getEmail(), subject, message);
});
} }
private String template(String templatePath, Map<String, Object> context) {
return mailTemplateProcessor.process(templatePath, context);
}
} }

36
core/src/main/java/com/databasir/core/infrastructure/mail/MailSender.java

@ -1,11 +1,14 @@
package com.databasir.core.infrastructure.mail; package com.databasir.core.infrastructure.mail;
import com.databasir.common.SystemException;
import com.databasir.dao.tables.pojos.SysMailPojo; import com.databasir.dao.tables.pojos.SysMailPojo;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -13,18 +16,29 @@ import java.util.Collections;
@Component @Component
public class MailSender { public class MailSender {
public void batchSend(SysMailPojo mail, Collection<String> to, String subject, String content) { public void sendHtml(SysMailPojo mail,
SimpleMailMessage message = new SimpleMailMessage(); String to,
message.setFrom(mail.getUsername()); String subject,
message.setTo(to.toArray(new String[0])); String content) {
message.setSubject(subject); this.batchSendHtml(mail, Collections.singleton(to), subject, content);
message.setText(content);
JavaMailSender sender = initJavaMailSender(mail);
sender.send(message);
} }
public void send(SysMailPojo mail, String to, String subject, String content) { public void batchSendHtml(SysMailPojo mail,
this.batchSend(mail, Collections.singleton(to), subject, content); Collection<String> to,
String subject,
String content) {
JavaMailSender sender = initJavaMailSender(mail);
MimeMessage mimeMessage = sender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(mail.getUsername());
helper.setTo(to.toArray(new String[0]));
helper.setSubject(subject);
helper.setText(content, true);
sender.send(mimeMessage);
} catch (MessagingException e) {
throw new SystemException("send mail error", e);
}
} }
private JavaMailSender initJavaMailSender(SysMailPojo properties) { private JavaMailSender initJavaMailSender(SysMailPojo properties) {

22
core/src/main/java/com/databasir/core/infrastructure/mail/MailTemplateConfig.java

@ -0,0 +1,22 @@
package com.databasir.core.infrastructure.mail;
import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import org.springframework.context.annotation.Bean;
@org.springframework.context.annotation.Configuration
public class MailTemplateConfig {
@Bean
public Configuration mailTemplateConfiguration() {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_29);
cfg.setClassForTemplateLoading(getClass(), "/");
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
cfg.setWrapUncheckedExceptions(true);
cfg.setFallbackOnNullLoopVariable(false);
return cfg;
}
}

30
core/src/main/java/com/databasir/core/infrastructure/mail/MailTemplateProcessor.java

@ -0,0 +1,30 @@
package com.databasir.core.infrastructure.mail;
import com.databasir.common.SystemException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
@Component
@RequiredArgsConstructor
public class MailTemplateProcessor {
private final Configuration mailTemplateConfiguration;
public String process(String templatePath, Map<String, Object> context) {
try {
Template template = mailTemplateConfiguration.getTemplate(templatePath);
StringWriter writer = new StringWriter();
template.process(context, writer);
return writer.toString();
} catch (IOException | TemplateException e) {
throw new SystemException("build template content error", e);
}
}
}

0
core/src/main/resources/ftl/mail/DiscussCreated.ftl

81
core/src/main/resources/ftl/mail/DocumentUpdated.ftl

@ -0,0 +1,81 @@
<html>
<body>
<div>
<table style="-webkit-font-smoothing:antialiased;margin:25px auto;background-repeat:no-repeat;background-position:0px 100px;text-align:left;border-radius:5px; padding:50px; background:#f3f4f6;width:800px"
border="0" cellspacing="0" cellpadding="0">
<tbody style="background-color:#ffffff;">
<tr>
<td colspan="2" width="50%"
style="font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei;line-height:24px; padding: 0px; margin: 0px;">
<div style="width: 700px;height: 80px;background: rgb(255, 255, 255);border-radius: 0px;">
<span style="background:#FFF;margin: 0px; padding:0px; vertical-align: center; margin-left: 55px;float: left;margin-top: 34px;">
Databasir
</span>
<span style="height: 14px;color: rgb(96, 108, 128);font-size: 14px;font-family: NotoSansCJKsc-Regular;font-weight: normal;text-align: center;letter-spacing: 0px;float: right;margin-top: 38px;margin-right: 10px;">专注于数据库文档管理</span>
</div>
<hr style=" border:none;border-top:1px solid #D8DDE4; margin-bottom: 30px;width: 640px;text-align:center"/>
</td>
</tr>
<tr>
<td style="line-height:30px; text-align:justify; font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei;padding: 0px; margin: 0px; background:#FFF; position:relative;"
colspan="4">
<div style="color:#323A45;background-color:#FFF;padding:0px 50px;">
<div style="background-color: rgba(235, 247, 255, 0.41); padding:10px 20px ;">
<p style="color: rgb(32, 45, 64);font-size: 14px;font-family: PingFangSC-Medium;font-weight: 0;letter-spacing: 0px;line-height: 12px;margin:0;margin-top: 20px;">
数据库&nbsp;<b>${projectName}</b>&nbsp;有新的文档变更:
</p>
<div style="margin-left: 20px; margin-top: 10px;background-size: 3px;background-repeat: no-repeat;">
<span style="padding:5px 8px 5px 8px; border:none ;background-color: transparent;">
<table style="text-align:center;width: 100%;color: #303133;font-size: 14px;font-family: PingFangSC-Medium;font-weight: 0;letter-spacing: 0px;line-height: 12px;">
<#list diffs as diff >
<#if diff.diffType == "MODIFIED">
<tr style="color:#E6A23C;background-color:#fdf6ec;padding:8px;border: 1px solid transparent;border-collapse: collapse;">
<td style="padding:8px;border-collapse: collapse;">${diff.tableName}</td>
<td style="padding:8px;border-collapse: collapse;">修改</td>
</tr>
<#elseif diff.diffType == "REMOVED">
<tr style="color:#F56C6C;background-color:#fef0f0;padding:8px;border: 1px solid transparent;border-collapse: collapse;">
<td style="padding:8px;border-collapse: collapse;">${diff.tableName}</td>
<td style="padding:8px;border-collapse: collapse;">删除</td>
</tr>
<#elseif diff.diffType == "ADDED">
<tr style="color:#67C23A;background-color:#f0f9eb;padding:8px;border: 1px solid transparent;border-collapse: collapse;">
<td style="padding:8px;border-collapse: collapse;">${diff.tableName}</td>
<td style="padding:8px;border-collapse: collapse;">新增</td>
</tr>
</#if>
</#list>
</table>
</span>
</div>
<p style="color:#606266;margin-top: 0px;">
详细变更内容请登录平台通过版本差异对比查看
</p>
</div>
</div>
</td>
</tr>
<tr>
<td style="text-align:center; font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei; padding: 0px; margin: 0px; background-color:#FFF; position:relative;"
colspan="4">
<div style="font-size:10px;color:#323A45; margin: 0px;padding:10px 40px;background-color:#FFF">
<hr style=" border:none;border-top:1px solid #D8DDE4; margin-bottom: 30px;width: 640px;text-align:center"/>
<p style="font-size:10px; line-height: 10px; color:#606c80;text-align: center">
<a href="https://doc.databasir.com" style="color: rgb(0, 102, 255);text-decoration:none;"
target="_blank">系统文档</a>
<span style="color: rgb(133, 146, 165);">|
<a href="https://github.com/vran-dev/databasir"
style="color: rgb(0, 102, 255);text-decoration:none;"
target="_blank">Databasir</a></span>
</p>
</div>
</td>
</tr>
</tbody>
</table>
<br/>
</div>
</body>
</html>

61
core/src/main/resources/ftl/mail/PasswordRenew.ftl

@ -0,0 +1,61 @@
<html>
<body>
<div>
<table style="-webkit-font-smoothing:antialiased;margin:25px auto;background-repeat:no-repeat;background-position:0px 100px;text-align:left;border-radius:5px; padding:50px; background:#f3f4f6;width:800px"
border="0" cellspacing="0" cellpadding="0">
<tbody style="background-color:#ffffff;">
<tr>
<td colspan="2" width="50%"
style="font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei;line-height:24px; padding: 0px; margin: 0px;">
<div style="width: 700px;height: 80px;background: rgb(255, 255, 255);border-radius: 0px;">
<span style="background:#FFF;margin: 0px; padding:0px; vertical-align: center; margin-left: 55px;float: left;margin-top: 34px;">
Databasir
</span>
<span style="height: 14px;color: rgb(96, 108, 128);font-size: 14px;font-family: NotoSansCJKsc-Regular;font-weight: normal;text-align: center;letter-spacing: 0px;float: right;margin-top: 38px;margin-right: 10px;">专注于数据库文档管理</span>
</div>
<hr style=" border:none;border-top:1px solid #D8DDE4; margin-bottom: 30px;width: 640px;text-align:center"/>
</td>
</tr>
<tr>
<td style="line-height:30px; text-align:justify; font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei;padding: 0px; margin: 0px; background:#FFF; position:relative;"
colspan="4">
<div style="color:#323A45;background-color:#FFF;padding:0px 50px;">
<div style="background-color: rgba(235, 247, 255, 0.41); padding:10px 20px ;">
<p style="color: rgb(32, 45, 64);font-size: 14px;font-family: PingFangSC-Medium;font-weight: 0;letter-spacing: 0px;line-height: 12px;margin:0;margin-top: 20px;">
尊敬的 ${nickname}:</p>
<p style="color: rgb(32, 45, 64);font-size: 14px;font-family: PingFangSC-Regular;font-weight: normal;letter-spacing: 0px;margin: 0;margin-top: 20px;text-indent:2em;">
您的密码已被 ${renewBy} 重置,为了您的账户安全,请尽快通过以下密码登录系统并修改密码
</p>
<div style="margin-left: 20px; margin-top: 10px;background-size: 3px;background-repeat: no-repeat;">
<span style="padding:5px 8px 5px 8px; border:none ;background-color: #F56C6C;">
<span target="_blank"
style="text-decoration:none; font-family:'Oracle Sans', Arial, sans-serif; color:#FFF;">
${newPassword}
</span>
</span>
</div>
</div>
</div>
</td>
</tr>
<tr>
<td style="text-align:center; font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei; padding: 0px; margin: 0px; background-color:#FFF; position:relative;"
colspan="4">
<div style="font-size:10px;color:#323A45; margin: 0px;padding:10px 40px;background-color:#FFF">
<hr style=" border:none;border-top:1px solid #D8DDE4; margin-bottom: 30px;width: 640px;text-align:center"/>
<p style="font-size:10px; line-height: 10px; color:#606c80;text-align: center">
<a href="https://doc.databasir.com" style="color: rgb(0, 102, 255);text-decoration:none;" target="_blank">系统文档</a>
<span style="color: rgb(133, 146, 165);">|
<a href="https://github.com/vran-dev/databasir"
style="color: rgb(0, 102, 255);text-decoration:none;" target="_blank">Databasir</a></span>
</p>
</div>
</td>
</tr>
</tbody>
</table>
<br/>
</div>
</body>
</html>

65
core/src/main/resources/ftl/mail/UserCreated.ftl

@ -0,0 +1,65 @@
<html>
<body>
<div>
<table style="-webkit-font-smoothing:antialiased;margin:25px auto;background-repeat:no-repeat;background-position:0px 100px;text-align:left;border-radius:5px; padding:50px; background:#f3f4f6;width:800px"
border="0" cellspacing="0" cellpadding="0">
<tbody style="background-color:#ffffff;">
<tr>
<td colspan="2" width="50%"
style="font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei;line-height:24px; padding: 0px; margin: 0px;">
<div style="width: 700px;height: 80px;background: rgb(255, 255, 255);border-radius: 0px;">
<span style="background:#FFF;margin: 0px; padding:0px; vertical-align: center; margin-left: 55px;float: left;margin-top: 34px;">
Databasir
</span>
<span style="height: 14px;color: rgb(96, 108, 128);font-size: 14px;font-family: NotoSansCJKsc-Regular;font-weight: normal;text-align: center;letter-spacing: 0px;float: right;margin-top: 38px;margin-right: 10px;">专注于数据库文档管理</span>
</div>
<hr style=" border:none;border-top:1px solid #D8DDE4; margin-bottom: 30px;width: 640px;text-align:center"/>
</td>
</tr>
<tr>
<td style="line-height:30px; text-align:justify; font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei;padding: 0px; margin: 0px; background:#FFF; position:relative;"
colspan="4">
<div style="color:#323A45;background-color:#FFF;padding:0px 50px;">
<div style="background-color: rgba(235, 247, 255, 0.41); padding:10px 20px ;">
<p style="color: rgb(32, 45, 64);font-size: 14px;font-family: PingFangSC-Medium;font-weight: 0;letter-spacing: 0px;line-height: 12px;margin:0;margin-top: 20px;">
尊敬的 ${nickname}:</p>
<p style="color: rgb(32, 45, 64);font-size: 14px;font-family: PingFangSC-Regular;font-weight: normal;letter-spacing: 0px;margin: 0;margin-top: 20px;text-indent:2em;">
您已成功注册 Databasir,用户名为 ${username}。
为了您的账号安全,请尽快通过以下密码登录系统并及时修改新密码
</p>
<div style="margin-left: 20px; margin-top: 10px;background-size: 3px;background-repeat: no-repeat;">
<span style="padding:5px 8px 5px 8px; border:none ;background-color: #F56C6C;">
<span target="_blank"
style="text-decoration:none; font-family:'Oracle Sans', Arial, sans-serif; color:#FFF;">
${newPassword}
</span>
</span>
</div>
</div>
</div>
</td>
</tr>
<tr>
<td style="text-align:center; font-family:'Microsoft Yahei','Helvetica Neue',sans-serif,SimHei; padding: 0px; margin: 0px; background-color:#FFF; position:relative;"
colspan="4">
<div style="font-size:10px;color:#323A45; margin: 0px;padding:10px 40px;background-color:#FFF">
<hr style=" border:none;border-top:1px solid #D8DDE4; margin-bottom: 30px;width: 640px;text-align:center"/>
<p style="font-size:10px; line-height: 10px; color:#606c80;text-align: center">
<a href="https://doc.databasir.com" style="color: rgb(0, 102, 255);text-decoration:none;"
target="_blank">系统文档</a>
<span style="color: rgb(133, 146, 165);">|
<a href="https://github.com/vran-dev/databasir"
style="color: rgb(0, 102, 255);text-decoration:none;"
target="_blank">Databasir</a></span>
</p>
</div>
</td>
</tr>
</tbody>
</table>
<br/>
</div>
</body>
</html>
Loading…
Cancel
Save