feat: emailConfig
This commit is contained in:
@@ -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 ? "是" : "否";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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: "全订阅" }
|
||||||
];
|
];
|
||||||
|
|
||||||
// 获取订阅列表
|
// 获取订阅列表
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
|
||||||
});
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
||||||
|
|||||||
Reference in New Issue
Block a user