feat: emailConfig

This commit is contained in:
2025-03-18 11:10:02 +08:00
parent 312662e587
commit 9329c8c22f
4 changed files with 264 additions and 26 deletions

View File

@@ -180,6 +180,7 @@ const columns: TableColumnList = [
label: "是否公司", label: "是否公司",
prop: "isCompany", prop: "isCompany",
width: "100", width: "100",
align: "center",
formatter: row => { formatter: row => {
return row.isCompany ? "是" : "否"; return row.isCompany ? "是" : "否";
} }

View File

@@ -78,7 +78,7 @@ const subTypeOptions = [
{ value: 0, label: "未指定" }, { value: 0, label: "未指定" },
{ value: 1, label: "求购" }, { value: 1, label: "求购" },
{ value: 2, label: "租赁" }, { value: 2, label: "租赁" },
{ value: 3, label: "全订阅" } { value: 9, label: "全订阅" }
]; ];
// 订阅领域选项 // 订阅领域选项
@@ -86,7 +86,7 @@ const subFieldOptions = [
{ value: 0, label: "未指定" }, { value: 0, label: "未指定" },
{ value: 1, label: "民航" }, { value: 1, label: "民航" },
{ value: 2, label: "通航" }, { value: 2, label: "通航" },
{ value: 3, label: "全订阅" } { value: 9, label: "全订阅" }
]; ];
// 订阅对象选项 // 订阅对象选项
@@ -94,7 +94,8 @@ const subCategoryOptions = [
{ value: 0, label: "未指定" }, { value: 0, label: "未指定" },
{ value: 1, label: "航材" }, { value: 1, label: "航材" },
{ value: 2, label: "飞机" }, { value: 2, label: "飞机" },
{ value: 3, label: "全订阅" } { value: 3, label: "工具" },
{ value: 9, label: "全订阅" }
]; ];
// 获取订阅列表 // 获取订阅列表

View File

@@ -32,6 +32,18 @@ const settingsData = ref({
}, },
area_config: { area_config: {
separator: " " separator: " "
},
email_config: {
smtpServer: "smtp.163.com",
smtpPort: "465",
auth: true,
sslEnable: true,
fromEmail: "silent3035@163.com",
fromEmailName: "Rocky",
fromEmailUser: "",
fromEmailPassword: "W0pPgIjQWMH0Tb2Y",
verifyEmail: "",
toEmails: ["silent3035@163.com", "zhanghuajun@rocky.com"]
} }
}); });
@@ -54,6 +66,11 @@ const separatorOptions = [
{ value: "_", label: "下划线" }, { value: "_", label: "下划线" },
{ value: ">", label: "大于号" } { value: ">", label: "大于号" }
]; ];
// 添加全局 loading 状态
const fullscreenLoading = ref(false);
// 添加邮箱相关状态
const showEmailInput = ref(false);
const newEmail = ref("");
// 加载设置数据 // 加载设置数据
const loadSettings = async () => { const loadSettings = async () => {
@@ -76,6 +93,7 @@ const loadSettings = async () => {
// 保存设置 // 保存设置
const saveSettings = async (key: string) => { const saveSettings = async (key: string) => {
try { try {
fullscreenLoading.value = true; // 显示遮罩层
const params = { const params = {
settingsKey: key, settingsKey: key,
settingsContent: JSON.stringify(settingsData.value[key]) settingsContent: JSON.stringify(settingsData.value[key])
@@ -92,6 +110,95 @@ const saveSettings = async (key: string) => {
} catch (error) { } catch (error) {
console.error("保存系统设置失败:", error); console.error("保存系统设置失败:", error);
ElMessage.error("保存系统设置失败"); ElMessage.error("保存系统设置失败");
} finally {
fullscreenLoading.value = false; // 隐藏遮罩层
}
};
// 添加邮箱
const handleAddEmail = () => {
const email = newEmail.value.trim();
if (email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
if (!settingsData.value.email_config.toEmails.includes(email)) {
settingsData.value.email_config.toEmails.push(email);
}
newEmail.value = "";
showEmailInput.value = false;
} else {
ElMessage.warning("请输入有效的邮箱地址");
}
};
// 移除邮箱
const handleRemoveEmail = (index: number) => {
settingsData.value.email_config.toEmails.splice(index, 1);
};
// 邮箱输入框失焦处理
const handleEmailInputBlur = () => {
if (newEmail.value.trim()) {
handleAddEmail();
}
showEmailInput.value = false;
};
// 邮箱格式校验函数
const isValidEmail = (email: string): boolean => {
// 标准邮箱格式正则表达式
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
return emailRegex.test(email);
};
// 发送测试邮件
const handleTestEmail = async () => {
// 校验发件邮箱配置
const { smtpServer, smtpPort, fromEmail, fromEmailPassword, fromEmailUser } =
settingsData.value.email_config;
if (
!smtpServer ||
!smtpPort ||
!fromEmail ||
!fromEmailPassword ||
!fromEmailUser
) {
ElMessage.warning("请先完成邮箱配置信息");
return;
}
// 校验发件邮箱格式
if (!isValidEmail(fromEmail)) {
ElMessage.warning("发件邮箱格式不正确,请检查配置");
return;
}
const email = settingsData.value.email_config.verifyEmail.trim();
// 检查邮箱是否为空
if (!email) {
ElMessage.warning("请输入测试邮箱地址");
return;
}
// 校验邮箱格式
if (!isValidEmail(email)) {
ElMessage.warning("请输入有效的邮箱地址");
return;
}
try {
const res = await request(bizApi("testEmail"), {
method: "POST",
body: JSON.stringify(settingsData.value.email_config)
});
if (res.status === 200) {
ElMessage.success("测试邮件发送成功, 邮箱服务器配置无误。");
} else {
ElMessage.error(res.msg || "测试邮件发送失败");
}
} catch (error) {
console.error("发送测试邮件失败:", error);
ElMessage.error("发送测试邮件失败");
} }
}; };
@@ -102,6 +209,12 @@ onMounted(() => {
<template> <template>
<div class="settings-container"> <div class="settings-container">
<div
v-loading.fullscreen.lock="fullscreenLoading"
:element-loading-text="'保存中...'"
class="settings-container"
/>
<!-- 发标设置 --> <!-- 发标设置 -->
<el-card class="settings-card"> <el-card class="settings-card">
<template #header> <template #header>
@@ -289,6 +402,125 @@ onMounted(() => {
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
<!-- 邮箱配置 -->
<el-card class="settings-card">
<template #header>
<div class="card-header">
<span>邮箱配置</span>
<el-button type="primary" @click="saveSettings('email_config')"
>保存</el-button
>
</div>
</template>
<el-form
label-width="160px"
:model="settingsData.email_config"
class="settings-form"
>
<el-form-item label="SMTP服务器">
<el-input
v-model="settingsData.email_config.smtpServer"
placeholder="请输入SMTP服务器地址"
style="width: 320px"
/>
</el-form-item>
<el-form-item label="SMTP端口">
<el-input
v-model="settingsData.email_config.smtpPort"
placeholder="请输入SMTP端口"
style="width: 320px"
/>
</el-form-item>
<el-form-item label="认证">
<el-switch v-model="settingsData.email_config.auth" disabled />
</el-form-item>
<el-form-item label="SSL加密">
<el-switch v-model="settingsData.email_config.sslEnable" disabled />
</el-form-item>
<el-form-item label="发件邮箱">
<el-input
v-model="settingsData.email_config.fromEmail"
placeholder="请输入发件邮箱"
style="width: 320px"
/>
</el-form-item>
<el-form-item label="发件邮箱名称">
<el-input
v-model="settingsData.email_config.fromEmailName"
placeholder="请输入发件邮箱名称"
style="width: 320px"
/>
</el-form-item>
<el-form-item label="发件邮箱用户名">
<el-input
v-model="settingsData.email_config.fromEmailUser"
placeholder="请输入发件邮箱用户名 Fomail、阿里邮箱非空"
style="width: 320px"
/>
<div class="form-tip">
注意:邮箱用户名默认发件邮箱@前部分。Foxmail邮箱需要单独配置为与之绑定的qq号码或者XXXX@qq.com的XXXX阿里云邮箱的用户名则是邮箱的完整地址。
</div>
</el-form-item>
<el-form-item label="发件邮箱密码/授权密钥">
<el-input
v-model="settingsData.email_config.fromEmailPassword"
type="password"
placeholder="请输入发件邮箱密码/授权密钥"
style="width: 320px"
show-password
/>
</el-form-item>
<el-form-item label="验证邮箱配置">
<el-input
v-model="settingsData.email_config.verifyEmail"
placeholder="请输入验证邮箱"
style="width: 320px"
>
<template #append>
<el-button @click="handleTestEmail">验证邮箱</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="收件邮箱列表">
<div class="email-list">
<el-tag
v-for="(email, index) in settingsData.email_config.toEmails"
:key="index"
class="email-tag"
closable
@close="handleRemoveEmail(index)"
>
{{ email }}
</el-tag>
<el-input
v-if="showEmailInput"
v-model="newEmail"
class="email-input"
placeholder="请输入邮箱并回车"
@keyup.enter="handleAddEmail"
@blur="handleEmailInputBlur"
/>
<el-button
v-else
class="button-new-email"
@click="showEmailInput = true"
>
+ 添加邮箱
</el-button>
</div>
</el-form-item>
</el-form>
</el-card>
</div> </div>
</template> </template>
@@ -306,7 +538,7 @@ onMounted(() => {
} }
.settings-form { .settings-form {
max-width: 600px; max-width: 1500px;
} }
.settings-table { .settings-table {
@@ -316,9 +548,35 @@ onMounted(() => {
.form-tip { .form-tip {
margin-top: 8px; margin-top: 8px;
margin-left: 6px;
font-size: 12px; font-size: 12px;
color: #909399; color: #909399;
} }
} }
} }
// 添加遮罩层相关样式
:deep(.el-loading-mask) {
background-color: rgb(255 255 255 / 80%);
}
.email-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
.email-tag {
margin-right: 8px;
}
.email-input {
width: 320px;
}
.button-new-email {
height: 32px;
padding: 0 12px;
}
}
</style> </style>

View File

@@ -48,28 +48,6 @@ export default ({ mode }: ConfigEnv): UserConfigExport => {
target: "http://127.0.0.1:9098", target: "http://127.0.0.1:9098",
changeOrigin: true, changeOrigin: true,
rewrite: path => path.replace(/^\/auth/, "/auth/user/rd") rewrite: path => path.replace(/^\/auth/, "/auth/user/rd")
/* configure: (proxy, options) => {
// 添加调试日志
proxy.on("proxyReq", (proxyReq, req, res) => {
console.log(res);
console.log("代理请求:", {
from: req.url,
to: options.target + proxyReq.path
});
});
proxy.on("proxyRes", (proxyRes, req, res) => {
console.log(res);
console.log("代理响应:", {
path: req.url,
status: proxyRes.statusCode
});
});
proxy.on("error", (err, req, res) => {
console.log(res);
console.log(req);
console.error("代理错误:", err);
});
} */
} }
}, },
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布 // 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布