refactor: reorganize email and message template responsibilities

This commit is contained in:
Crane.z
2026-04-13 13:41:43 +08:00
parent 05069d6397
commit 938e46da62
3 changed files with 187 additions and 147 deletions

View File

@@ -1,66 +0,0 @@
<template>
<div>
<el-button size="mini" type="primary" icon="el-icon-setting" @click="visible = !visible"> {{
$t("Setting")
}}
</el-button>
<Dialog
v-if="visible"
:show-cancel="false"
:show-confirm="false"
:title="$tc('EmailTemplate')"
:visible.sync="visible"
width="70%"
@confirm="onConfirm()"
>
<GenericCreateUpdateForm v-bind="$data" />
</Dialog>
</div>
</template>
<script>
import GenericCreateUpdateForm from '@/layout/components/GenericCreateUpdateForm/index.vue'
import { Dialog } from '@/components'
export default {
name: 'MsgTemplate',
components: {
GenericCreateUpdateForm,
Dialog
},
data() {
return {
visible: false,
fields: [
[this.$t('General'), ['EMAIL_SUBJECT_PREFIX']],
[this.$t('CreateUserContent'),
[
'EMAIL_CUSTOM_USER_CREATED_SUBJECT', 'EMAIL_CUSTOM_USER_CREATED_HONORIFIC', 'EMAIL_CUSTOM_USER_CREATED_BODY'
]
]
],
successUrl: { name: 'Settings', params: { activeMenu: 'EmailContent' } },
fieldsMeta: {
'EMAIL_CUSTOM_USER_CREATED_BODY': {
el: {
type: 'textarea',
rows: 3
}
}
},
url: '/api/v1/settings/setting/?category=email_content',
submitMethod() {
return 'patch'
},
onConfirm() {
}
}
},
methods: {}
}
</script>
<style scoped>
</style>

View File

@@ -8,19 +8,36 @@
v-bind="$data"
/>
</IBox>
<Dialog
:visible.sync="testDialogVisible"
:title="$t('EmailTest')"
:disabled-status="testButtonLoading"
width="500px"
@confirm="handleTestConfirm"
@cancel="handleTestCancel"
>
<el-form label-width="100px">
<el-form-item :label="$t('Recipient')" :error="testRecipientError">
<el-input
v-model.trim="testRecipient"
@keyup.enter.native="handleTestConfirm"
/>
</el-form-item>
</el-form>
</Dialog>
</div>
</template>
<script>
import { IBox } from '@/components'
import { Dialog, IBox } from '@/components'
import { GenericCreateUpdateForm } from '@/layout/components'
import { testEmailSetting } from '@/api/settings'
import rules from '@/components/Form/DataForm/rules'
import EmailTemplate from './EmailTemplate.vue'
export default {
name: 'Email',
components: {
Dialog,
GenericCreateUpdateForm,
IBox
},
@@ -41,26 +58,15 @@ export default {
'EMAIL_FROM',
'EMAIL_SECURITY_PROTOCOL'
]
],
[this.$t('Other'), ['CREATE_USER_MSG']],
[this.$t('Test'), ['EMAIL_RECIPIENT']]
]
],
fieldsMeta: {
EMAIL_PORT: {
hidden: formValue => formValue.EMAIL_PROTOCOL !== 'smtp'
},
EMAIL_CUSTOM_USER_CREATED_BODY: {
el: {
type: 'textarea',
rows: 3
}
},
EMAIL_FROM: {
rules: [rules.EmailCheck]
},
EMAIL_RECIPIENT: {
rules: [rules.EmailCheck]
},
EMAIL_SECURITY_PROTOCOL: {
hidden: formValue => formValue.EMAIL_PROTOCOL !== 'smtp',
label: this.$t('UseSSL'),
@@ -71,12 +77,6 @@ export default {
{ label: this.$t('SSL'), value: 'ssl' },
{ label: this.$t('TLS'), value: 'tls' }
]
},
CREATE_USER_MSG: {
label: this.$t('EmailTemplate'),
component: EmailTemplate,
helpTip: this.$t('EmailTemplateHelpTip')
}
},
afterGetFormValue(obj) {
@@ -92,30 +92,26 @@ export default {
hasDetailInMsg: false,
successUrl: { name: 'Msg' },
url: '/api/v1/settings/setting/?category=email',
testDialogVisible: false,
testButtonLoading: false,
testRecipient: '',
testRecipientError: '',
testFormValue: {},
moreButtons: [
{
title: this.$t('EmailTest'),
loading: false,
callback: function (value, form, btn) {
const testValue = {}
testValue['EMAIL_FROM'] = value['EMAIL_FROM']
testValue['EMAIL_RECIPIENT'] = value['EMAIL_RECIPIENT']
btn.loading = true
testEmailSetting(value)
.then(res => {
vm.$message.success(res['msg'])
})
.catch(res => {
vm.$message.error(res['response']['data']['error'])
})
.finally(() => {
btn.loading = false
})
callback: function(value, form, btn) {
vm.testFormValue = { ...value }
vm.testRecipient = ''
vm.testRecipientError = ''
vm.testButtonLoading = false
vm.testDialogVisible = true
}
}
],
cleanFormValue(data) {
Object.keys(data).forEach(function (key) {
Object.keys(data).forEach(function(key) {
if (data[key] === null) {
delete data[key]
}
@@ -144,7 +140,41 @@ export default {
}
}
},
methods: {}
methods: {
handleTestCancel() {
this.testDialogVisible = false
this.testButtonLoading = false
this.testRecipientError = ''
},
handleTestConfirm() {
const recipient = this.testRecipient
if (!recipient) {
this.testRecipientError = this.$t('FieldRequiredError')
return
}
if (!/\S+@\S+\.\S+/.test(recipient)) {
this.testRecipientError = this.$t('InputEmailAddress')
return
}
this.testRecipientError = ''
this.testButtonLoading = true
testEmailSetting({
EMAIL_FROM: this.testFormValue.EMAIL_FROM,
EMAIL_RECIPIENT: recipient
})
.then(res => {
this.$message.success(res.msg)
this.testDialogVisible = false
})
.catch(res => {
this.$message.error(res.response.data.error)
})
.finally(() => {
this.testButtonLoading = false
})
}
}
}
</script>

View File

@@ -2,11 +2,13 @@
<div>
<IBox>
<GenericCreateUpdateForm
:key="templateFormKey"
:create-success-next-route="successUrl"
:update-success-next-route="successUrl"
v-bind="$data"
/>
</IBox>
<VariablesHelpTextDialog
:variables-help-text="variablesHelpText"
:variables="variables"
@@ -35,15 +37,27 @@ export default {
const vm = this
return {
initial: {
template_name: localStorage.getItem('selectTemplateName') || 'terminal/_msg_session_sharing.html'
EMAIL_SUBJECT_PREFIX: '',
template_name: localStorage.getItem('selectTemplateName') || 'users/_msg_user_created.html',
template_content: ''
},
fields: [
[this.$t('Basic'), [
'EMAIL_SUBJECT_PREFIX',
'template_name',
'template_content'
]]
],
fieldsMeta: {
EMAIL_SUBJECT_PREFIX: {
rules: [
{
required: true,
message: this.$t('FieldRequiredError'),
trigger: 'blur'
}
]
},
template_name: {
label: this.$t('Name'),
helpTextFormatter: () => {
@@ -51,7 +65,9 @@ export default {
this.showHelpDialog = true
}
return (
<i onClick={handleClick} class='fa fa-question-circle' style='cursor: pointer'>{this.$t('Help')}</i>
<i onClick={handleClick} class='fa fa-question-circle' style='cursor: pointer'>
{this.$t('Help')}
</i>
)
},
component: Select2,
@@ -62,20 +78,9 @@ export default {
on: {
input: ([event], updateForm) => {
setTimeout(() => {
vm.templates.map(item => {
if (item.template_name === event) {
this.selectTemplateName = item.template_name
localStorage.setItem('selectTemplateName', item.template_name)
this.variables = item.contexts
this.source = item.source
updateForm({
template_content: item.content.trimStart()
})
}
})
},
500
)
const selectedTemplate = vm.templates.find(item => item.template_name === event)
vm.applySelectedTemplate(selectedTemplate, updateForm)
}, 500)
}
}
},
@@ -89,6 +94,7 @@ export default {
}
},
templates: [],
templateFormKey: 0,
successUrl: { name: 'Msg' },
showHelpDialog: false,
variables: [],
@@ -96,30 +102,45 @@ export default {
source: 'original',
selectTemplateName: '',
variablesHelpText: this.$t('TemplateVariablesHelpText'),
hasButtons: true,
hasSaveContinue: false,
onPerformError() {
},
performSubmit(validValues) {
validValues['render_html'] = vm.html
return this.$axios['patch']('/api/v1/notifications/templates/edit/', validValues).then(res => {
this.$router.push({ name: 'Msg', query: { t: new Date().getTime() } })
})
},
moreButtons: [
{
title: this.$t('Reset'),
type: 'default',
// hidden: () => this.source === 'original',
callback: (value, form, btn) => {
return this.$axios['post']('/api/v1/notifications/templates/reset/', { template_name: this.selectTemplateName }).then(
() => {
this.$router.push({ name: 'Msg', query: { t: new Date().getTime() } })
this.$message.success(this.$t('ResetSuccessfully'))
}
)
loading: false,
callback: async function(value, form, btn) {
btn.loading = true
try {
const templateName = value.template_name || vm.selectTemplateName || vm.initial.template_name
await vm.$axios.post('/api/v1/notifications/templates/reset/', {
template_name: templateName
})
await vm.fetchTemplates()
vm.$message.success(vm.$t('ResetSuccessfully'))
} finally {
btn.loading = false
}
}
}
]
],
performSubmit(validValues) {
const payload = { ...validValues }
payload.render_html = vm.html
return vm.$axios.patch('/api/v1/settings/setting/?category=email_content', {
EMAIL_SUBJECT_PREFIX: payload.EMAIL_SUBJECT_PREFIX
}).then(() => {
return vm.$axios.patch('/api/v1/notifications/templates/edit/', {
template_name: payload.template_name,
template_content: payload.template_content,
render_html: payload.render_html
})
}).then(() => {
vm.$router.push({ name: 'Msg', query: { t: new Date().getTime() } })
})
}
}
},
computed: {
@@ -131,21 +152,76 @@ export default {
this.fetchTemplates()
},
methods: {
fetchTemplates() {
this.$axios.get('/api/v1/notifications/templates/').then(data => {
if (data.length > 0) {
this.templates = data
this.fieldsMeta.template_name.el.options = data.map(item => ({
label: item.subject,
value: item.template_name
}))
applyEmailContentFieldMeta(remoteMeta = {}) {
const emailSubjectPrefixMeta = remoteMeta.EMAIL_SUBJECT_PREFIX || {}
this.fieldsMeta.EMAIL_SUBJECT_PREFIX = {
label: emailSubjectPrefixMeta.label,
helpText: emailSubjectPrefixMeta.help_text,
rules: this.fieldsMeta.EMAIL_SUBJECT_PREFIX.rules
}
},
applySelectedTemplate(template, updateForm) {
if (!template) {
return
}
this.selectTemplateName = template.template_name
localStorage.setItem('selectTemplateName', template.template_name)
this.variables = template.contexts
this.source = template.source
this.html = template.content || ''
if (typeof updateForm === 'function') {
updateForm({
template_name: template.template_name,
template_content: (template.content || '').trimStart()
})
}
},
async fetchTemplates() {
try {
const [templates, emailSettings, emailContentMeta] = await Promise.all([
this.$axios.get('/api/v1/notifications/templates/'),
this.$axios.get('/api/v1/settings/setting/?category=email_content'),
this.$store.dispatch('common/getUrlMeta', {
url: '/api/v1/settings/setting/?category=email_content'
})
])
this.applyEmailContentFieldMeta(emailContentMeta.actions.PATCH || {})
if (!templates.length) {
this.$message.warning(this.$t('NoData'))
return
}
})
this.templates = templates
this.fieldsMeta.template_name.el.options = templates.map(item => ({
label: item.subject,
value: item.template_name
}))
const initialTemplateName = this.initial.template_name
const selectedTemplate = templates.find(item => item.template_name === initialTemplateName) || templates[0]
this.initial = {
...this.initial,
EMAIL_SUBJECT_PREFIX: emailSettings.EMAIL_SUBJECT_PREFIX || '',
template_name: selectedTemplate.template_name,
template_content: (selectedTemplate.content || '').trimStart()
}
this.variables = selectedTemplate.contexts
this.source = selectedTemplate.source
this.html = selectedTemplate.content || ''
this.selectTemplateName = selectedTemplate.template_name
localStorage.setItem('selectTemplateName', selectedTemplate.template_name)
this.templateFormKey += 1
} catch (error) {
const message = error?.response?.data?.error || error?.message || this.$t('UnknownError')
this.$message.error(message)
}
}
}
}
</script>
<style scoped>
</style>
<style scoped></style>