Smail/frontend/src/views/components/ConfigSettings/RelayConfig/RelayConfig.vue
smail 3cca3438b8
Some checks are pending
Security Checks / security (push) Waiting to run
增加SMTP中继开关与配置管理
新增中继启用控制、列表展示、编辑和清除逻辑,保留安全配置边界。
2026-10-06 00:20:29 +08:00

107 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="relay-config">
<div class="relay-list-heading">
<div>
<h5>已配置的 SMTP 中继</h5>
<p>中继配置独立于本机邮件服务;关闭开关只停止使用,不会删除已填写的信息。</p>
</div>
<el-button v-if="hasConfigured && !editing" type="primary" plain :disabled="disabled" @click="editing = true">
编辑中继
</el-button>
</div>
<el-alert
v-if="relay.clear"
title="已标记清除,保存后将删除服务器、端口、账号、密码、发件邮箱和发件域名。"
type="warning"
:closable="false"
show-icon
class="relay-alert"
/>
<div v-if="hasConfigured && !editing" class="relay-list" role="list" aria-label="SMTP 中继列表">
<article class="relay-item" role="listitem">
<div class="relay-item-heading">
<div>
<strong>默认 SMTP 中继</strong>
<span class="relay-subtitle">单个默认发信中继配置</span>
</div>
<el-tag :type="relay.enabled ? 'success' : 'info'" effect="plain">
{{ relay.enabled ? '已启用' : '已关闭' }}
</el-tag>
</div>
<dl class="relay-summary">
<div><dt>SMTP 服务器</dt><dd>{{ relay.relayHost || '未填写' }}</dd></div>
<div><dt>端口</dt><dd>{{ relay.relayPort || '未填写' }}</dd></div>
<div><dt>认证账号</dt><dd>{{ relay.username || '未填写' }}</dd></div>
<div><dt>发件邮箱</dt><dd>{{ relay.from || '未填写' }}</dd></div>
<div><dt>密码</dt><dd>{{ passwordConfigured ? '已配置(不显示明文)' : '未配置' }}</dd></div>
<div><dt>发件域名</dt><dd>{{ relay.fromDomain || '未填写' }}</dd></div>
</dl>
<div class="relay-item-actions">
<el-button type="primary" plain :disabled="disabled" @click="editing = true">编辑</el-button>
<el-button type="danger" plain :disabled="disabled" @click="clearRelay">清除中继</el-button>
</div>
</article>
</div>
<el-empty v-else-if="!editing" description="暂无已配置的 SMTP 中继" />
<div v-if="editing" class="relay-editor">
<div class="relay-editor-heading">
<h5>{{ hasConfigured ? '编辑 SMTP 中继' : '添加 SMTP 中继' }}</h5>
<span>密码留空表示保持原值,清除操作需要单独点击“清除中继”。</span>
</div>
<div class="form-grid relay-fields">
<ConfigField
v-for="field in fields"
:key="fieldKey(field)"
:field="field"
:value="getValue(config, field.path)"
:error="errors[fieldKey(field)]"
:disabled="disabled"
@change="(path, value) => emit('change', path, value)"
/>
</div>
<div class="relay-editor-actions">
<el-button v-if="hasConfigured" :disabled="disabled" @click="editing = false">取消编辑</el-button>
<el-button v-if="hasConfigured" type="danger" plain :disabled="disabled" @click="clearRelay">清除中继</el-button>
</div>
</div>
</div>
</template>
<script setup>
import { computed, ref } from 'vue'
import { ElMessageBox } from 'element-plus'
import ConfigField from '../ConfigField/ConfigField.vue'
import { fieldKey, getValue, relayConfigured } from '../ConfigForm/ConfigForm.js'
const props = defineProps({
config: { type: Object, required: true },
fields: { type: Array, required: true },
errors: { type: Object, default: () => ({}) },
disabled: Boolean
})
const emit = defineEmits(['change'])
const relay = computed(() => props.config.relay || {})
const hasConfigured = computed(() => relayConfigured(props.config))
const passwordConfigured = computed(() => !!props.config.relayPasswordStatus?.configured)
const editing = ref(!hasConfigured.value)
const clearRelay = async () => {
try {
await ElMessageBox.confirm(
'清除后将删除已保存的 SMTP 中继信息和密码,关闭中继开关不会产生此影响。确认清除吗?',
'确认清除 SMTP 中继',
{ type: 'warning', confirmButtonText: '确认清除', cancelButtonText: '取消' }
)
emit('change', ['relay', 'clear'], true)
editing.value = false
} catch (error) {
if (error !== 'cancel' && error !== 'close') throw error
}
}
</script>
<style scoped src="./RelayConfig.css"></style>