chore: email template优化

This commit is contained in:
xiaojunnuo
2025-12-14 23:19:32 +08:00
parent a6c0d2c6f1
commit de544ec725
9 changed files with 64 additions and 67 deletions

View File

@@ -1,9 +1,9 @@
<template>
<div class="params-show">
<div v-for="item of params" :key="item.value" class="item">
<span class="label">{{ item.label }}:</span>
<fs-copyable>{{ item.value }}</fs-copyable>
</div>
<a-tag type="primary" color="green" v-for="item of params" :key="item.value" class="item">
<span class="label">{{ item.label }}=</span>
<fs-copyable :modelValue="`\$\{${item.value}\}`" :button="{show:false}" :inline="true"></fs-copyable>
</a-tag>
</div>
</template>
<script setup lang="ts">
@@ -21,20 +21,13 @@ const props = defineProps<{
display: flex;
flex-wrap: wrap;
align-items: center;
min-height: 32px;
.item {
width: 200px;
display: flex;
margin-bottom: 5px;
align-items: center;
.label {
width: 100px;
}
.fs-copyable {
width: 100%;
}
margin-bottom: 2px;
margin-top: 2px;
}
}
</style>

View File

@@ -18,24 +18,24 @@ export class EmailController extends BaseController {
return this.ok({});
}
// @Post('/list', { summary: Constants.per.authOnly })
// public async list() {
// const userId = super.getUserId();
// const res = await this.emailService.list(userId);
// return this.ok(res);
// }
@Post('/list', { summary: Constants.per.authOnly })
public async list() {
const userId = super.getUserId();
const res = await this.emailService.list(userId);
return this.ok(res);
}
// @Post('/add', { summary: Constants.per.authOnly })
// public async add(@Body('email') email) {
// const userId = super.getUserId();
// await this.emailService.add(userId, email);
// return this.ok({});
// }
@Post('/add', { summary: Constants.per.authOnly })
public async add(@Body('email') email) {
const userId = super.getUserId();
await this.emailService.add(userId, email);
return this.ok({});
}
// @Post('/delete', { summary: Constants.per.authOnly })
// public async delete(@Body('email') email) {
// const userId = super.getUserId();
// await this.emailService.delete(userId, email);
// return this.ok({});
// }
@Post('/delete', { summary: Constants.per.authOnly })
public async delete(@Body('email') email) {
const userId = super.getUserId();
await this.emailService.delete(userId, email);
return this.ok({});
}
}

View File

@@ -172,11 +172,13 @@ export class EmailService implements IEmailService {
// 没有找到模版,使用默认模版
if (!content) {
try {
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getBlank(req.type, "默认")
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getBlank("emailTemplate", req.type)
content = await addon.buildDefaultContent({ data: req.data })
} catch (e) {
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getBlank("common", "默认")
// 对应的通知类型模版可能没有注册或者开发
const addon: ITemplateProvider<EmailContent> = await this.addonGetterService.getBlank("emailTemplate", "common")
content = await addon.buildDefaultContent({ data: req.data })
//common类型的一定有已经开发了
}
}
return await this.send({

View File

@@ -63,9 +63,9 @@ export class AddonGetterService {
}
async getBlank(type:string,name:string){
async getBlank(addonType:string,subType:string){
return await this.getAddonById(null,false,0,{
type,name
type: addonType, name:subType
})
}

View File

@@ -1,5 +1,4 @@
import { AddonInput, BaseAddon } from "@certd/lib-server";
import { get } from "lodash-es";
import { BuildContentReq, EmailContent, ITemplateProvider } from "../api.js";
export class BaseEmailTemplateProvider extends BaseAddon implements ITemplateProvider<EmailContent> {
@@ -9,10 +8,10 @@ export class BaseEmailTemplateProvider extends BaseAddon implements ITemplatePro
name: "a-alert",
props: {
type: "info",
message: "在标题和内容模版中,通过${param}引用参数,例如: 感谢注册${siteTitle},您的注册验证码为:${code}",
message: "在标题和内容模版中,通过${name}引用参数,例如: 感谢注册,您的注册验证码为:${code}",
}
},
order: 1,
order: -9,
col: { span: 24 },
})
useIntro = "";
@@ -29,7 +28,7 @@ export class BaseEmailTemplateProvider extends BaseAddon implements ITemplatePro
]
}
},
order: 1,
order: 9,
col: { span: 24 },
})
formatType = "";
@@ -80,13 +79,20 @@ export class BaseEmailTemplateProvider extends BaseAddon implements ITemplatePro
throw new Error("请实现 buildDefaultContent 方法")
}
compile(templateString: string) {
return function (data: any): string {
return templateString.replace(/\${(.*?)}/g, (match, key) => {
const value = get(data, key, '');
return String(value);
});
};
// compile(templateString: string) {
// return function (data: any): string {
// return templateString.replace(/\${(.*?)}/g, (match, key) => {
// const value = get(data, key?.trim(), '');
// return String(value);
// });
// };
// }
compile(templateString:string) {
return new Function('data', ` with(data || {}) {
return \`${templateString}\`;
}
`);
}
}

View File

@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate",
name: 'common',
title: '通用邮件模版',
desc: '通用邮件模版',
desc: '使用通用邮件标题和内容内容外部可以自定义html进行美化',
icon: "simple-icons:email:blue",
showTest: false,
})
@@ -16,12 +16,11 @@ export class CommonEmailTemplateProvider extends BaseEmailTemplateProvider imple
component: {
name: "ParamsShow",
params:[
{labele:"标题",value:"title"},
{labele:"内容",value:"content"},
{labele:"URL",value:"url"}
{label:"标题",value:"title"},
{label:"内容",value:"content"},
{label:"URL",value:"url"}
]
},
order: 5,
col: { span: 24 },
})
paramIntro = "";
@@ -30,7 +29,7 @@ export class CommonEmailTemplateProvider extends BaseEmailTemplateProvider imple
async buildDefaultContent(req:BuildContentReq) {
const defaultTemplate = new CommonEmailTemplateProvider()
defaultTemplate.titleTemplate = "${title}"
defaultTemplate.contentTemplate = "${content} \n\n 查看详情:${url}"
defaultTemplate.contentTemplate = "${content} \n\n 查看详情${url}"
defaultTemplate.formatType = "text"
return await defaultTemplate.buildContent(req)
}

View File

@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate",
name: 'forgotPassword',
title: '忘记密码邮件模版',
desc: '忘记密码邮件模版',
desc: '您正在重置密码您的验证码为xxxx请勿泄露',
icon: "simple-icons:email:blue",
showTest: false,
})
@@ -16,10 +16,9 @@ export class ForgotPasswordEmailTemplateProvider extends BaseEmailTemplateProvid
component: {
name: "ParamsShow",
params:[
{labele:"验证码",value:"code"}
{label:"验证码",value:"code"}
]
},
order: 5,
col: { span: 24 },
})
paramIntro = "";

View File

@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate",
name: 'pipelineResult',
title: '流水线执行结果邮件模版',
desc: '流水线执行结果邮件模版',
desc: '执行失败xxxx自动化【流水线id】运行ID:xxx,错误信息:xxxx',
icon: "simple-icons:email:blue",
showTest: false,
})
@@ -16,15 +16,14 @@ export class PipelineResultEmailTemplateProvider extends BaseEmailTemplateProvid
component: {
name: "ParamsShow",
params:[
{labele:"运行结果",value:"pipelineResult"},
{labele:"流水线标题",value:"pipelineTitle"},
{labele:"流水线ID",value:"pipelineId"},
{labele:"运行Id",value:"historyId"},
{labele:"错误信息",value:"errors"},
{labele:"URL",value:"url"},
{label:"运行结果",value:"pipelineResult"},
{label:"流水线标题",value:"pipelineTitle"},
{label:"流水线ID",value:"pipelineId"},
{label:"运行Id",value:"historyId"},
{label:"错误信息",value:"errors"},
{label:"URL",value:"url"},
]
},
order: 5,
col: { span: 24 },
})
paramIntro = "";

View File

@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate",
name: 'registerCode',
title: '注册验证码邮件模版',
desc: '注册验证码邮件模版',
desc: '您的注册验证码xxxx请勿泄露',
icon: "simple-icons:email:blue",
showTest: false,
})
@@ -16,10 +16,9 @@ export class RegisterCodeEmailTemplateProvider extends BaseEmailTemplateProvider
component: {
name: "ParamsShow",
params:[
{labele:"验证码",value:"code"}
{label:"验证码",value:"code"}
]
},
order: 5,
col: { span: 24 },
})
paramIntro = "";