feat: emailConfig
This commit is contained in:
@@ -180,6 +180,7 @@ const columns: TableColumnList = [
|
||||
label: "是否公司",
|
||||
prop: "isCompany",
|
||||
width: "100",
|
||||
align: "center",
|
||||
formatter: row => {
|
||||
return row.isCompany ? "是" : "否";
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ const subTypeOptions = [
|
||||
{ value: 0, label: "未指定" },
|
||||
{ value: 1, label: "求购" },
|
||||
{ value: 2, label: "租赁" },
|
||||
{ value: 3, label: "全订阅" }
|
||||
{ value: 9, label: "全订阅" }
|
||||
];
|
||||
|
||||
// 订阅领域选项
|
||||
@@ -86,7 +86,7 @@ const subFieldOptions = [
|
||||
{ value: 0, label: "未指定" },
|
||||
{ value: 1, label: "民航" },
|
||||
{ value: 2, label: "通航" },
|
||||
{ value: 3, label: "全订阅" }
|
||||
{ value: 9, label: "全订阅" }
|
||||
];
|
||||
|
||||
// 订阅对象选项
|
||||
@@ -94,7 +94,8 @@ const subCategoryOptions = [
|
||||
{ value: 0, label: "未指定" },
|
||||
{ value: 1, label: "航材" },
|
||||
{ value: 2, label: "飞机" },
|
||||
{ value: 3, label: "全订阅" }
|
||||
{ value: 3, label: "工具" },
|
||||
{ value: 9, label: "全订阅" }
|
||||
];
|
||||
|
||||
// 获取订阅列表
|
||||
|
||||
@@ -32,6 +32,18 @@ const settingsData = ref({
|
||||
},
|
||||
area_config: {
|
||||
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: "大于号" }
|
||||
];
|
||||
// 添加全局 loading 状态
|
||||
const fullscreenLoading = ref(false);
|
||||
// 添加邮箱相关状态
|
||||
const showEmailInput = ref(false);
|
||||
const newEmail = ref("");
|
||||
|
||||
// 加载设置数据
|
||||
const loadSettings = async () => {
|
||||
@@ -76,6 +93,7 @@ const loadSettings = async () => {
|
||||
// 保存设置
|
||||
const saveSettings = async (key: string) => {
|
||||
try {
|
||||
fullscreenLoading.value = true; // 显示遮罩层
|
||||
const params = {
|
||||
settingsKey: key,
|
||||
settingsContent: JSON.stringify(settingsData.value[key])
|
||||
@@ -92,6 +110,95 @@ const saveSettings = async (key: string) => {
|
||||
} catch (error) {
|
||||
console.error("保存系统设置失败:", 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>
|
||||
<div class="settings-container">
|
||||
<div
|
||||
v-loading.fullscreen.lock="fullscreenLoading"
|
||||
:element-loading-text="'保存中...'"
|
||||
class="settings-container"
|
||||
/>
|
||||
|
||||
<!-- 发标设置 -->
|
||||
<el-card class="settings-card">
|
||||
<template #header>
|
||||
@@ -289,6 +402,125 @@ onMounted(() => {
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
@@ -306,7 +538,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.settings-form {
|
||||
max-width: 600px;
|
||||
max-width: 1500px;
|
||||
}
|
||||
|
||||
.settings-table {
|
||||
@@ -316,9 +548,35 @@ onMounted(() => {
|
||||
|
||||
.form-tip {
|
||||
margin-top: 8px;
|
||||
margin-left: 6px;
|
||||
font-size: 12px;
|
||||
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>
|
||||
|
||||
@@ -48,28 +48,6 @@ export default ({ mode }: ConfigEnv): UserConfigExport => {
|
||||
target: "http://127.0.0.1:9098",
|
||||
changeOrigin: true,
|
||||
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);
|
||||
});
|
||||
} */
|
||||
}
|
||||
},
|
||||
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
||||
|
||||
Reference in New Issue
Block a user