chore: email template

This commit is contained in:
xiaojunnuo
2025-12-12 23:39:09 +08:00
parent 43ba0b9da6
commit 437d956cad
8 changed files with 106 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
export function isDev() {
const nodeEnv = process.env.NODE_ENV || '';
const nodeEnv = process.env.NODE_ENV || 'dev';
return nodeEnv === 'development' || nodeEnv.includes('local') || nodeEnv.startsWith('dev');
}

View File

@@ -6,7 +6,7 @@
"type": "module",
"scripts": {
"start": "cross-env NODE_ENV=production node --optimize-for-size ./bootstrap.js",
"dev-start": "mwtsc --watch --run @midwayjs/mock/app",
"dev-start": "cross-env NODE_ENV=dev & mwtsc --watch --run @midwayjs/mock/app",
"dc": "cd ../../../ && pnpm run dev",
"dev": "cross-env NODE_ENV=local & pnpm run dev-start",
"dev-commlocal": "cross-env NODE_ENV=dev-commlocal mwtsc --watch --run @midwayjs/mock/app",

View File

@@ -26,6 +26,7 @@ export class AutoZPrint {
async init() {
//监听https
this.startHttpsServer();
logger.info("ENV:", process.env.NODE_ENV);
if (isDev()) {
this.startHeapLog();
}
@@ -49,7 +50,7 @@ export class AutoZPrint {
setInterval(() => {
const mu = process.memoryUsage();
logger.info(`rss:${format(mu.rss)},heapUsed: ${format(mu.heapUsed)},heapTotal: ${format(mu.heapTotal)},external: ${format(mu.external)}`);
}, 60000);
}, 20000);
}
startHttpsServer() {

View File

@@ -109,8 +109,14 @@ export class CodeService {
const code = randomNumber(verificationCodeLength);
const templateData = {
code, duration, siteTitle
}
const titleTemplate = opts?.title?
const title = `${siteTitle}${!!opts?.title ? opts.title : '验证码'}`;
const content = !!opts.content ? this.compile(opts.content)({code, duration}) : `您的验证码是${code},请勿泄露`;
const content = !!opts.content ? this.compile(opts.content)(templateData) : `您的验证码是${code},请勿泄露`;
await this.emailService.send({
subject: title,

View File

@@ -0,0 +1,10 @@
export type BuildContentReq = {
data: any;
}
export type BuildContentReply = Record<string, string>;
export interface ITemplateProvider {
buildContent: (params: BuildContentReq) => Promise<BuildContentReply>;
}

View File

@@ -0,0 +1,57 @@
import { AddonInput, BaseAddon } from "@certd/lib-server";
import { BuildContentReply, BuildContentReq, ITemplateProvider } from "../api.js";
import { get } from "lodash-es";
export class BaseEmailTemplateProvider extends BaseAddon implements ITemplateProvider {
@AddonInput({
title: "配置说明",
component:{
name:"a-alert",
props:{
type:"info",
message:"在标题和内容模版中,通过${param}引用参数,例如: 感谢注册${siteTitle},您的注册验证码为:${code}",
}
},
order: 1,
col:{span:24},
})
useIntro = "";
@AddonInput({
title: "邮件标题模版",
required: true,
order: 10,
})
titleTemplate = "";
@AddonInput({
title: "邮件内容模版",
component: {
placeholder: "邮件内容模版",
},
order: 20,
required: true,
})
contentTemplate = "";
async buildContent(params: BuildContentReq) : Promise<BuildContentReply>{
const title = this.compile(this.titleTemplate)(params.data)
const content = this.compile(this.contentTemplate)(params.data)
return {
title,
content,
}
};
compile(templateString: string) {
return function(data:any):string {
return templateString.replace(/\${(.*?)}/g, (match, key) => {
const value = get(data, key, '');
return String(value);
});
};
}
}

View File

@@ -0,0 +1,28 @@
import { AddonInput, IsAddon } from "@certd/lib-server";
import { BaseEmailTemplateProvider } from "./plugin-base.js";
@IsAddon({
addonType: "emailTemplate",
name: 'register',
title: '注册邮件模版',
desc: '注册邮件模版',
icon:"simple-icons:gitee:red",
showTest: false,
})
export class RegisterEmailTemplateProvider extends BaseEmailTemplateProvider {
@AddonInput({
title: "可用参数",
component:{
name:"a-alert",
props:{
type:"info",
message:"站点名称:${siteTitle};注册验证码:${code};有效期:${duration}分钟",
}
},
order: 5,
col:{span:24},
})
paramIntro = "";
}