feat: update mail template
This commit is contained in:
parent
92bb5a1742
commit
bd28279588
|
@ -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}"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
sysMailDao.selectOptionTopOne().ifPresent(mail -> {
|
||||||
ProjectPojo project = projectDao.selectById(created.getProjectId());
|
ProjectPojo project = projectDao.selectById(created.getProjectId());
|
||||||
List<String> to = userDao.selectEnabledGroupMembers(project.getGroupId())
|
List<String> to = userDao.selectEnabledGroupMembers(project.getGroupId())
|
||||||
.stream()
|
.stream()
|
||||||
|
.filter(UserPojo::getEnabled)
|
||||||
.map(UserPojo::getEmail)
|
.map(UserPojo::getEmail)
|
||||||
.filter(mail -> mail.contains("@"))
|
.filter(userEmail -> userEmail.contains("@"))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
sysMailDao.selectOptionTopOne().ifPresent(mail -> {
|
String subject = project.getName() + " 文档有新的内容变更";
|
||||||
String subject = project.getName() + " 文档有新的版本";
|
List<Map<String, String>> diffs = created.getDiff()
|
||||||
String message = created.getDiff()
|
.map(this::diffs)
|
||||||
.map(diff -> build(diff))
|
.orElseGet(Collections::emptyList);
|
||||||
.orElseGet(() -> "首次文档同步常规");
|
Map<String, Object> context = new HashMap<>();
|
||||||
mailSender.batchSend(mail, to, subject, message);
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
|
||||||
event.getNickname(), event.getUsername(), event.getRawPassword());
|
|
||||||
} else {
|
|
||||||
message = String.format("Hi %s\r\n您的 Databasir 账户已创建成功,用户名:%s",
|
|
||||||
event.getNickname(), event.getUsername());
|
|
||||||
}
|
|
||||||
sysMailDao.selectOptionTopOne()
|
sysMailDao.selectOptionTopOne()
|
||||||
.ifPresent(mailPojo -> {
|
.ifPresent(mailPojo -> {
|
||||||
mailSender.send(mailPojo, event.getEmail(), subject, message);
|
Map<String, Object> context = new HashMap<>();
|
||||||
|
context.put("nickname", event.getNickname());
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String template(String templatePath, Map<String, Object> context) {
|
||||||
|
return mailTemplateProcessor.process(templatePath, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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,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;">
|
||||||
|
数据库 <b>${projectName}</b> 有新的文档变更:
|
||||||
|
</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>
|
||||||
|
|
|
@ -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>
|
|
@ -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…
Reference in New Issue