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
@@ -1,9 +1,9 @@
<template> <template>
<div class="params-show"> <div class="params-show">
<div v-for="item of params" :key="item.value" class="item"> <a-tag type="primary" color="green" v-for="item of params" :key="item.value" class="item">
<span class="label">{{ item.label }}:</span> <span class="label">{{ item.label }}=</span>
<fs-copyable>{{ item.value }}</fs-copyable> <fs-copyable :modelValue="`\$\{${item.value}\}`" :button="{show:false}" :inline="true"></fs-copyable>
</div> </a-tag>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -21,20 +21,13 @@ const props = defineProps<{
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
min-height: 32px;
.item { .item {
width: 200px;
display: flex; display: flex;
margin-bottom: 5px;
align-items: center; align-items: center;
margin-bottom: 2px;
.label { margin-top: 2px;
width: 100px;
}
.fs-copyable {
width: 100%;
}
} }
} }
</style> </style>
@@ -18,24 +18,24 @@ export class EmailController extends BaseController {
return this.ok({}); return this.ok({});
} }
// @Post('/list', { summary: Constants.per.authOnly }) @Post('/list', { summary: Constants.per.authOnly })
// public async list() { public async list() {
// const userId = super.getUserId(); const userId = super.getUserId();
// const res = await this.emailService.list(userId); const res = await this.emailService.list(userId);
// return this.ok(res); return this.ok(res);
// } }
// @Post('/add', { summary: Constants.per.authOnly }) @Post('/add', { summary: Constants.per.authOnly })
// public async add(@Body('email') email) { public async add(@Body('email') email) {
// const userId = super.getUserId(); const userId = super.getUserId();
// await this.emailService.add(userId, email); await this.emailService.add(userId, email);
// return this.ok({}); return this.ok({});
// } }
// @Post('/delete', { summary: Constants.per.authOnly }) @Post('/delete', { summary: Constants.per.authOnly })
// public async delete(@Body('email') email) { public async delete(@Body('email') email) {
// const userId = super.getUserId(); const userId = super.getUserId();
// await this.emailService.delete(userId, email); await this.emailService.delete(userId, email);
// return this.ok({}); return this.ok({});
// } }
} }
@@ -172,11 +172,13 @@ export class EmailService implements IEmailService {
// 没有找到模版,使用默认模版 // 没有找到模版,使用默认模版
if (!content) { if (!content) {
try { 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 }) content = await addon.buildDefaultContent({ data: req.data })
} catch (e) { } 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 }) content = await addon.buildDefaultContent({ data: req.data })
//common类型的一定有,已经开发了
} }
} }
return await this.send({ return await this.send({
@@ -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,{ return await this.getAddonById(null,false,0,{
type,name type: addonType, name:subType
}) })
} }
@@ -1,5 +1,4 @@
import { AddonInput, BaseAddon } from "@certd/lib-server"; import { AddonInput, BaseAddon } from "@certd/lib-server";
import { get } from "lodash-es";
import { BuildContentReq, EmailContent, ITemplateProvider } from "../api.js"; import { BuildContentReq, EmailContent, ITemplateProvider } from "../api.js";
export class BaseEmailTemplateProvider extends BaseAddon implements ITemplateProvider<EmailContent> { export class BaseEmailTemplateProvider extends BaseAddon implements ITemplateProvider<EmailContent> {
@@ -9,10 +8,10 @@ export class BaseEmailTemplateProvider extends BaseAddon implements ITemplatePro
name: "a-alert", name: "a-alert",
props: { props: {
type: "info", type: "info",
message: "在标题和内容模版中,通过${param}引用参数,例如: 感谢注册${siteTitle},您的注册验证码为:${code}", message: "在标题和内容模版中,通过${name}引用参数,例如: 感谢注册,您的注册验证码为:${code}",
} }
}, },
order: 1, order: -9,
col: { span: 24 }, col: { span: 24 },
}) })
useIntro = ""; useIntro = "";
@@ -29,7 +28,7 @@ export class BaseEmailTemplateProvider extends BaseAddon implements ITemplatePro
] ]
} }
}, },
order: 1, order: 9,
col: { span: 24 }, col: { span: 24 },
}) })
formatType = ""; formatType = "";
@@ -80,13 +79,20 @@ export class BaseEmailTemplateProvider extends BaseAddon implements ITemplatePro
throw new Error("请实现 buildDefaultContent 方法") throw new Error("请实现 buildDefaultContent 方法")
} }
compile(templateString: string) { // compile(templateString: string) {
return function (data: any): string { // return function (data: any): string {
return templateString.replace(/\${(.*?)}/g, (match, key) => { // return templateString.replace(/\${(.*?)}/g, (match, key) => {
const value = get(data, key, ''); // const value = get(data, key?.trim(), '');
return String(value); // return String(value);
}); // });
}; // };
// }
compile(templateString:string) {
return new Function('data', ` with(data || {}) {
return \`${templateString}\`;
}
`);
} }
} }
@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate", addonType: "emailTemplate",
name: 'common', name: 'common',
title: '通用邮件模版', title: '通用邮件模版',
desc: '通用邮件模版', desc: '使用通用邮件标题和内容,内容外部可以自定义html进行美化',
icon: "simple-icons:email:blue", icon: "simple-icons:email:blue",
showTest: false, showTest: false,
}) })
@@ -16,12 +16,11 @@ export class CommonEmailTemplateProvider extends BaseEmailTemplateProvider imple
component: { component: {
name: "ParamsShow", name: "ParamsShow",
params:[ params:[
{labele:"标题",value:"title"}, {label:"标题",value:"title"},
{labele:"内容",value:"content"}, {label:"内容",value:"content"},
{labele:"URL",value:"url"} {label:"URL",value:"url"}
] ]
}, },
order: 5,
col: { span: 24 }, col: { span: 24 },
}) })
paramIntro = ""; paramIntro = "";
@@ -30,7 +29,7 @@ export class CommonEmailTemplateProvider extends BaseEmailTemplateProvider imple
async buildDefaultContent(req:BuildContentReq) { async buildDefaultContent(req:BuildContentReq) {
const defaultTemplate = new CommonEmailTemplateProvider() const defaultTemplate = new CommonEmailTemplateProvider()
defaultTemplate.titleTemplate = "${title}" defaultTemplate.titleTemplate = "${title}"
defaultTemplate.contentTemplate = "${content} \n\n 查看详情:${url}" defaultTemplate.contentTemplate = "${content} \n\n 查看详情${url}"
defaultTemplate.formatType = "text" defaultTemplate.formatType = "text"
return await defaultTemplate.buildContent(req) return await defaultTemplate.buildContent(req)
} }
@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate", addonType: "emailTemplate",
name: 'forgotPassword', name: 'forgotPassword',
title: '忘记密码邮件模版', title: '忘记密码邮件模版',
desc: '忘记密码邮件模版', desc: '您正在重置密码,您的验证码为xxxx,请勿泄露',
icon: "simple-icons:email:blue", icon: "simple-icons:email:blue",
showTest: false, showTest: false,
}) })
@@ -16,10 +16,9 @@ export class ForgotPasswordEmailTemplateProvider extends BaseEmailTemplateProvid
component: { component: {
name: "ParamsShow", name: "ParamsShow",
params:[ params:[
{labele:"验证码",value:"code"} {label:"验证码",value:"code"}
] ]
}, },
order: 5,
col: { span: 24 }, col: { span: 24 },
}) })
paramIntro = ""; paramIntro = "";
@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate", addonType: "emailTemplate",
name: 'pipelineResult', name: 'pipelineResult',
title: '流水线执行结果邮件模版', title: '流水线执行结果邮件模版',
desc: '流水线执行结果邮件模版', desc: '执行失败,xxxx自动化【流水线id】;运行ID:xxx,错误信息:xxxx',
icon: "simple-icons:email:blue", icon: "simple-icons:email:blue",
showTest: false, showTest: false,
}) })
@@ -16,15 +16,14 @@ export class PipelineResultEmailTemplateProvider extends BaseEmailTemplateProvid
component: { component: {
name: "ParamsShow", name: "ParamsShow",
params:[ params:[
{labele:"运行结果",value:"pipelineResult"}, {label:"运行结果",value:"pipelineResult"},
{labele:"流水线标题",value:"pipelineTitle"}, {label:"流水线标题",value:"pipelineTitle"},
{labele:"流水线ID",value:"pipelineId"}, {label:"流水线ID",value:"pipelineId"},
{labele:"运行Id",value:"historyId"}, {label:"运行Id",value:"historyId"},
{labele:"错误信息",value:"errors"}, {label:"错误信息",value:"errors"},
{labele:"URL",value:"url"}, {label:"URL",value:"url"},
] ]
}, },
order: 5,
col: { span: 24 }, col: { span: 24 },
}) })
paramIntro = ""; paramIntro = "";
@@ -6,7 +6,7 @@ import { BaseEmailTemplateProvider } from "./plugin-base.js";
addonType: "emailTemplate", addonType: "emailTemplate",
name: 'registerCode', name: 'registerCode',
title: '注册验证码邮件模版', title: '注册验证码邮件模版',
desc: '注册验证码邮件模版', desc: '您的注册验证码为:xxxx,请勿泄露',
icon: "simple-icons:email:blue", icon: "simple-icons:email:blue",
showTest: false, showTest: false,
}) })
@@ -16,10 +16,9 @@ export class RegisterCodeEmailTemplateProvider extends BaseEmailTemplateProvider
component: { component: {
name: "ParamsShow", name: "ParamsShow",
params:[ params:[
{labele:"验证码",value:"code"} {label:"验证码",value:"code"}
] ]
}, },
order: 5,
col: { span: 24 }, col: { span: 24 },
}) })
paramIntro = ""; paramIntro = "";