新增tg和第三方邮件转发

This commit is contained in:
eoao
2025-06-28 13:35:37 +08:00
parent 010e0451ab
commit 136c0496b8
25 changed files with 948 additions and 457 deletions

View File

@@ -125,7 +125,7 @@
<span>
<Icon icon="mdi-light:email" width="20" height="20"/>
</span>
<span>{{ item.status === 7 ? formateReceive(item.recipient) : item.accountEmail }}</span>
<span>{{ item.toEmail }}</span>
</div>
<div class="del-status" v-if="item.isDel">
<el-tag type="info" size="small">已删除</el-tag>

View File

@@ -39,6 +39,8 @@ function updateContent() {
const bodyStyleMatch = props.html.match(bodyStyleRegex);
const bodyStyle = bodyStyleMatch ? bodyStyleMatch[1] : '';
console.log(bodyStyle)
// 2. 移除 <body> 标签(保留内容)
const cleanedHtml = props.html.replace(/<\/?body[^>]*>/gi, '');
@@ -63,19 +65,11 @@ function updateContent() {
${bodyStyle ? bodyStyle : ''} /* 注入 body 的 style */
}
img {
img:not(table img) {
max-width: 100%;
height: auto !important;
}
*:not(p) {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: inherit;
-webkit-tap-highlight-color: transparent;
}
</style>
<div class="shadow-content">
${cleanedHtml}

View File

@@ -4,7 +4,7 @@ import { useAccountStore } from "@/store/account.js";
import { loginUserInfo } from "@/request/my.js";
import { permsToRouter } from "@/utils/perm.js";
import router from "@/router";
import { settingQuery } from "@/request/setting.js";
import { websiteConfig } from "@/request/setting.js";
import {cvtR2Url} from "@/utils/convert.js";
export async function init() {
@@ -24,7 +24,7 @@ export async function init() {
return null;
});
const [s, user] = await Promise.all([settingQuery(), userPromise]);
const [s, user] = await Promise.all([websiteConfig(), userPromise]);
setting = s;
settingStore.settings = setting;
settingStore.domainList = setting.domainList;
@@ -41,7 +41,7 @@ export async function init() {
}
} else {
setting = await settingQuery();
setting = await websiteConfig();
settingStore.settings = setting;
settingStore.domainList = setting.domainList;
document.title = setting.title;

View File

@@ -7,7 +7,7 @@
<el-scrollbar class="scrollbar">
<div v-infinite-scroll="getAccountList" :infinite-scroll-distance="600" :infinite-scroll-immediate="false">
<el-card class="item" :class="itemBg(item.accountId)" v-for="item in accounts" :key="item.accountId" @click="changeAccount(item)">
<div class="account">
<div class="account" @click.stop>
{{ item.email }}
</div>
<div class="opt">

View File

@@ -1,6 +1,6 @@
<template>
<div class="send" v-show="show">
<div class="write-box">
<div class="send" v-show="show" @click="close">
<div class="write-box" @click.stop>
<div class="title">
<div class="title-left">
<span class="title-text">

View File

@@ -4,7 +4,7 @@ import router from './router';
import './style.css';
import VueCropper from 'vue-cropper';
import 'vue-cropper/dist/index.css'
import { init } from '@/utils/init.js';
import { init } from '@/init/init.js';
import { createPinia } from 'pinia';
import piniaPersistedState from 'pinia-plugin-persistedstate';
import perm from "@/directives/perm.js";

View File

@@ -8,6 +8,10 @@ export function settingQuery() {
return http.get('/setting/query')
}
export function websiteConfig() {
return http.get('/setting/websiteConfig')
}
export function setBackground(background) {
return http.put('/setting/setBackground',{background})
}

View File

@@ -78,8 +78,10 @@
>注册
</el-button>
</div>
<div class="switch" @click="show = 'register'" v-if="show === 'login'">还有没有账号? <span>创建账号</span></div>
<div class="switch" @click="show = 'login'" v-else>有账号? <span>去登录</span></div>
<template v-if="settingStore.settings.register === 0">
<div class="switch" @click="show = 'register'" v-if="show === 'login'">还有没有账号? <span>创建账号</span></div>
<div class="switch" @click="show = 'login'" v-else>已有账号? <span>去登录</span></div>
</template>
</div>
</div>
</div>

View File

@@ -74,7 +74,7 @@ defineOptions({
const emailStore = useEmailStore();
const sysEmailScroll = ref({})
const searchType = ref('user')
const searchType = ref('name')
const searchValue = ref('')
const mySelect = ref()

View File

@@ -1,240 +1,277 @@
<template>
<div class="settings-container">
<el-scrollbar class="scroll">
<div class="card-grid">
<!-- Website Settings Card -->
<div class="settings-card">
<div class="card-title">网站设置</div>
<div class="card-content">
<div class="setting-item">
<div><span>用户注册</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.register"/>
<div v-if="firstLoading" class="loading">
<loading />
</div>
<el-scrollbar class="scroll" v-else >
<div class="scroll-body">
<div class="card-grid">
<!-- Website Settings Card -->
<div class="settings-card">
<div class="card-title">网站设置</div>
<div class="card-content">
<div class="setting-item">
<div><span>用户注册</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.register"/>
</div>
</div>
</div>
<div class="setting-item">
<div><span>添加邮箱</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.addEmail"/>
<div class="setting-item">
<div><span>添加邮箱</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.addEmail"/>
</div>
</div>
</div>
<div class="setting-item">
<div>
<span>多号模式</span>
<el-tooltip effect="dark" content="开启后账号栏出现一个用户可以添加多个邮箱">
<Icon class="warning" icon="fe:warning" width="20" height="20"/>
</el-tooltip>
<div class="setting-item">
<div>
<span>多号模式</span>
<el-tooltip effect="dark" content="开启后账号栏出现一个用户可以添加多个邮箱">
<Icon class="warning" icon="fe:warning" width="18" height="18"/>
</el-tooltip>
</div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.manyEmail"/>
</div>
</div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.manyEmail"/>
<div class="setting-item">
<div>
<span>轮询刷新</span>
<el-tooltip effect="dark" content="轮询请求服务器获取最新邮件">
<Icon class="warning" icon="fe:warning" width="18" height="18"/>
</el-tooltip>
</div>
<div>
<el-select
@change="change"
style="width: 80px;"
v-model="setting.autoRefreshTime"
placeholder="Select"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
</div>
<div class="setting-item">
<div>
<span>轮询刷新</span>
<el-tooltip effect="dark" content="轮询请求服务器获取最新邮件">
<Icon class="warning" icon="fe:warning" width="20" height="20"/>
</el-tooltip>
</div>
<div>
<el-select
@change="change"
style="width: 80px;"
v-model="setting.autoRefreshTime"
placeholder="Select"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
<div class="setting-item">
<div>
<span>物理清空数据</span>
<el-tooltip effect="dark" content="该操作会物理清空所有已被删除的数据">
<Icon class="warning" icon="fe:warning" width="20" height="20"/>
</el-tooltip>
</div>
<div>
<el-button class="opt-button" style="margin-top: 0" @click="physicsDeleteAllData" size="small"
type="primary">
<Icon icon="material-symbols:delete-outline-rounded" width="16" height="16"/>
</el-button>
</div>
</div>
</div>
</div>
<!-- Personalization Settings Card -->
<div class="settings-card">
<div class="card-title">个性化设置</div>
<div class="card-content">
<div class="setting-item">
<div class="title-item"><span>网站标题</span></div>
<div class="email-title">
<span>{{ setting.title }}</span>
<el-button class="opt-button" size="small" type="primary" @click="editTitleShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
</div>
</div>
<div class="setting-item">
<div class="title-item"><span>登录透明</span></div>
<div>
<el-input-number size="small" v-model="loginOpacity" @change="opacityChange" :precision="2" :step="0.01" :max="1" :min="0" />
</div>
</div>
<div class="setting-item personalized">
<div><span>登录背景</span></div>
<div>
<el-image
class="background"
:src="cvtR2Url(setting.background)"
:preview-src-list="[cvtR2Url(setting.background)]"
show-progress
fit="cover"
>
<template #error>
<div class="error-image" @click="openCut">
<Icon icon="ph:image" width="24" height="24"/>
</div>
</template>
</el-image>
<div class="background-btn">
<el-button class="opt-button" size="small" type="primary" @click="openCut">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
<el-button class="opt-button" size="small" type="primary" @click="delBackground">
<div class="setting-item">
<div>
<span>物理清空数据</span>
<el-tooltip effect="dark" content="该操作会物理清空所有已被删除的数据">
<Icon class="warning" icon="fe:warning" width="18" height="18"/>
</el-tooltip>
</div>
<div>
<el-button class="opt-button" style="margin-top: 0" @click="physicsDeleteAllData" size="small"
type="primary">
<Icon icon="material-symbols:delete-outline-rounded" width="16" height="16"/>
</el-button>
</div>
</div>
</div>
</div>
</div>
<!-- Email Sending Settings Card -->
<div class="settings-card">
<div class="card-title">邮件设置</div>
<div class="card-content">
<div class="setting-item">
<div><span>邮件接收</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.receive"/>
<!-- Personalization Settings Card -->
<div class="settings-card">
<div class="card-title">个性化设置</div>
<div class="card-content">
<div class="setting-item">
<div class="title-item"><span>网站标题</span></div>
<div class="email-title">
<span>{{ setting.title }}</span>
<el-button class="opt-button" size="small" type="primary" @click="editTitleShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
</div>
</div>
</div>
<div class="setting-item">
<div><span>邮件发送</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.send"/>
<div class="setting-item">
<div class="title-item"><span>登录透明</span></div>
<div>
<el-input-number size="small" v-model="loginOpacity" @change="opacityChange" :precision="2" :step="0.01" :max="1" :min="0" />
</div>
</div>
</div>
<div class="setting-item">
<div><span>添加resend令牌</span></div>
<div>
<el-button class="opt-button" style="margin-top: 0" @click="openResendForm" size="small" type="primary">
<Icon icon="material-symbols:add-rounded" width="16" height="16"/>
</el-button>
</div>
</div>
<div class="setting-item token-item" v-for="(value, key, index) in setting.resendTokens" :key="index">
<div><span>{{ key }}</span></div>
<div><span>{{ value }}</span></div>
</div>
</div>
</div>
<!-- R2 Object Storage Card -->
<div class="settings-card">
<div class="card-title">R2对象存储</div>
<div class="card-content">
<div class="setting-item">
<div><span>访问域名</span></div>
<div class="r2domain">
<span>{{ setting.r2Domain || '空' }}</span>
<el-button class="opt-button" size="small" type="primary" @click="r2DomainShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
<div class="setting-item personalized">
<div><span>登录背景</span></div>
<div>
<el-image
class="background"
:src="cvtR2Url(setting.background)"
:preview-src-list="[cvtR2Url(setting.background)]"
show-progress
fit="cover"
>
<template #error>
<div class="error-image" @click="openCut">
<Icon icon="ph:image" width="24" height="24"/>
</div>
</template>
</el-image>
<div class="background-btn">
<el-button class="opt-button" size="small" type="primary" @click="openCut">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
<el-button class="opt-button" size="small" type="primary" @click="delBackground">
<Icon icon="material-symbols:delete-outline-rounded" width="16" height="16"/>
</el-button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Turnstile Verification Card -->
<div class="settings-card">
<div class="card-title">Turnstile 人机验证</div>
<div class="card-content">
<div class="setting-item">
<div><span>注册验证</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.registerVerify"/>
<!-- Email Sending Settings Card -->
<div class="settings-card">
<div class="card-title">邮件设置</div>
<div class="card-content">
<div class="setting-item">
<div><span>邮件接收</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.receive"/>
</div>
</div>
</div>
<div class="setting-item">
<div><span>添加验证</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.addEmailVerify"/>
<div class="setting-item">
<div><span>邮件发送</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.send"/>
</div>
</div>
</div>
<div class="setting-item">
<div><span>siteKey</span></div>
<div class="bot-verify">
<span>{{ setting.siteKey || '空' }}</span>
<el-button class="opt-button" size="small" type="primary" @click="turnstileShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
<div class="setting-item">
<div><span>添加 Resend Token</span></div>
<div>
<el-button class="opt-button" style="margin-top: 0" @click="openResendForm" size="small" type="primary">
<Icon icon="material-symbols:add-rounded" width="16" height="16"/>
</el-button>
</div>
</div>
</div>
<div class="setting-item">
<div><span>secretKey</span></div>
<div class="bot-verify">
<span> {{ setting.secretKey || '空' }} </span>
<el-button class="opt-button" size="small" type="primary" @click="turnstileShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
<div class="setting-item token-item" v-for="(value, key, index) in setting.resendTokens" :key="index">
<div><span>{{ key }}</span></div>
<div><span>{{ value }}</span></div>
</div>
</div>
</div>
</div>
<div class="settings-card">
<div class="card-title">关于</div>
<div class="card-content">
<div class="concerning-item">
<span>版本:</span>
<span>v1.2.1</span>
<!-- R2 Object Storage Card -->
<div class="settings-card">
<div class="card-title">R2对象存储</div>
<div class="card-content">
<div class="setting-item">
<div><span>访问域名</span></div>
<div class="r2domain">
<span>{{ setting.r2Domain || '空' }}</span>
<el-button class="opt-button" size="small" type="primary" @click="r2DomainShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
</div>
</div>
</div>
<div class="concerning-item">
<span>交流:</span>
<el-button @click="jump('https://t.me/cloud_mail_tg')">
telegram
<template #icon>
<Icon icon="logos:telegram" width="30" height="30"/>
</template>
</el-button>
<el-button @click="jump('https://github.com/LaziestRen/cloud-mail')">
github
<template #icon>
<Icon icon="codicon:github-inverted" width="22" height="22" />
</template>
</el-button>
</div>
<div class="settings-card">
<div class="card-title">邮件转发通知</div>
<div class="card-content">
<div class="setting-item">
<div><span>Telegram 机器人</span></div>
<div class="forward">
<span>{{ setting.tgBotStatus === 0 ? '已开启' : '已关闭' }}</span>
<el-button class="opt-button" size="small" type="primary" @click="openTgSetting">
<Icon icon="fluent:settings-48-regular" width="18" height="18"/>
</el-button>
</div>
</div>
<div class="setting-item">
<div><span>第三方邮箱</span></div>
<div class="forward">
<span>{{ setting.forwardStatus === 0 ? '已开启' : '已关闭' }}</span>
<el-button class="opt-button" size="small" type="primary" @click="openThirdEmailSetting">
<Icon icon="fluent:settings-48-regular" width="18" height="18"/>
</el-button>
</div>
</div>
<div class="setting-item">
<div><span>转发规则</span></div>
<div class="forward">
<span>{{ setting.ruleType === 0 ? '全部转发' : '规则转发' }}</span>
<el-button class="opt-button" size="small" type="primary" @click="openForwardRules">
<Icon icon="fluent:settings-48-regular" width="18" height="18"/>
</el-button>
</div>
</div>
</div>
</div>
<!-- Turnstile Verification Card -->
<div class="settings-card">
<div class="card-title">Turnstile 人机验证</div>
<div class="card-content">
<div class="setting-item">
<div><span>注册验证</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.registerVerify"/>
</div>
</div>
<div class="setting-item">
<div><span>添加验证</span></div>
<div>
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
v-model="setting.addEmailVerify"/>
</div>
</div>
<div class="setting-item">
<div><span>Site Key</span></div>
<div class="bot-verify">
<span>{{ setting.siteKey || '空' }}</span>
<el-button class="opt-button" size="small" type="primary" @click="turnstileShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
</div>
</div>
<div class="setting-item">
<div><span>Secret Key</span></div>
<div class="bot-verify">
<span> {{ setting.secretKey || '空' }} </span>
<el-button class="opt-button" size="small" type="primary" @click="turnstileShow = true">
<Icon icon="lsicon:edit-outline" width="16" height="16"/>
</el-button>
</div>
</div>
</div>
</div>
<div class="settings-card about">
<div class="card-title">关于</div>
<div class="card-content">
<div class="concerning-item">
<span>版本:</span>
<span>v1.2.1</span>
</div>
<div class="concerning-item">
<span>交流:</span>
<el-button @click="jump('https://t.me/cloud_mail_tg')">
telegram
<template #icon>
<Icon icon="logos:telegram" width="30" height="30"/>
</template>
</el-button>
<el-button @click="jump('https://github.com/LaziestRen/cloud-mail')">
github
<template #icon>
<Icon icon="codicon:github-inverted" width="22" height="22" />
</template>
</el-button>
</div>
</div>
</div>
</div>
</div>
<!-- Dialogs remain the same -->
<el-dialog v-model="editTitleShow" title="修改标题" width="340" @closed="editTitle = ''">
<form>
@@ -242,7 +279,7 @@
<el-button type="primary" :loading="settingLoading" @click="saveTitle">保存</el-button>
</form>
</el-dialog>
<el-dialog v-model="resendTokenFormShow" title="添加resend令牌" width="340" @closed="cleanResendTokenForm">
<el-dialog v-model="resendTokenFormShow" title="添加resend token" width="340" @closed="cleanResendTokenForm">
<form>
<el-select style="margin-bottom: 15px" v-model="resendTokenForm.domain" placeholder="Select">
<el-option
@@ -292,6 +329,83 @@
<el-button type="primary" :loading="settingLoading" @click="saveBackground">保存</el-button>
</div>
</el-dialog>
<el-dialog
v-model="tgSettingShow"
title="Telegram 机器人"
class="forward-dialog"
>
<template #header>
<div class="forward-head">
<span class="forward-set-title">Telegram 机器人</span>
<el-tooltip effect="dark" content="可以将接收的邮件转发到Tg机器人">
<Icon class="warning" icon="fe:warning" width="18" height="18"/>
</el-tooltip>
</div>
</template>
<div class="forward-set-body">
<el-input placeholder="机器人 token" v-model="tgBotToken"></el-input>
<el-input-tag tag-type="warning" placeholder="用户 chat_id 多个用,分开 12345,54321" v-model="tgChatId" @add-tag="addChatTag" ></el-input-tag>
</div>
<template #footer>
<div class="dialog-footer">
<el-switch v-model="tgBotStatus" :active-value="0" :inactive-value="1" active-text="开启" inactive-text="关闭" />
<el-button :loading="settingLoading" type="primary" @click="tgBotSave">
保存
</el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="thirdEmailShow"
class="forward-dialog"
>
<template #header>
<div class="forward-head">
<span class="forward-set-title">第三方邮箱</span>
<el-tooltip effect="dark" trigger="click" content="可以将邮件转到其他服务商邮箱需要在cloudflare验证邮箱">
<Icon class="warning" icon="fe:warning" width="18" height="18"/>
</el-tooltip>
</div>
</template>
<div class="forward-set-body">
<el-input-tag tag-type="warning" placeholder="多邮个箱用, 分开 example1.com,example2.com" v-model="forwardEmail" @add-tag="emailAddTag"></el-input-tag>
</div>
<template #footer>
<div class="dialog-footer">
<el-switch v-model="forwardStatus" :active-value="0" :inactive-value="1" active-text="开启" inactive-text="关闭" />
<el-button :loading="settingLoading" type="primary" @click="forwardEmailSave">
保存
</el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="forwardRulesShow"
class="forward-dialog"
>
<template #header>
<div class="forward-head">
<span class="forward-set-title">转发规则</span>
<el-tooltip effect="dark" content="规则转发只会转发设置邮箱所接收的邮件">
<Icon class="warning" icon="fe:warning" width="18" height="18"/>
</el-tooltip>
</div>
</template>
<div class="forward-set-body">
<el-input-tag placeholder="多邮个箱用, 分开 example1.com,example2.com" tag-type="success" v-model="ruleEmail" @add-tag="ruleEmailAddTag" />
</div>
<template #footer>
<div class="dialog-footer">
<el-radio-group v-model="ruleType">
<el-radio :value="0" >全部转发</el-radio>
<el-radio :value="1" >规则转发</el-radio>
</el-radio-group>
<el-button :loading="settingLoading" type="primary" @click="ruleEmailSave">
保存
</el-button>
</div>
</template>
</el-dialog>
</el-scrollbar>
</div>
</template>
@@ -306,11 +420,14 @@ import {Icon} from "@iconify/vue";
import {cvtR2Url} from "@/utils/convert.js";
import {storeToRefs} from "pinia";
import { debounce } from 'lodash-es'
import {isEmail} from "@/utils/verify-utils.js";
import loading from "@/components/loading/index.vue";
defineOptions({
name: 'sys-setting'
})
const firstLoading = ref(true)
const cropper = ref()
const cutImage = ref('')
const cutShow = ref(false)
@@ -320,6 +437,9 @@ const editTitleShow = ref(false)
const resendTokenFormShow = ref(false)
const r2DomainShow = ref(false)
const turnstileShow = ref(false)
const tgSettingShow = ref(false)
const thirdEmailShow = ref(false)
const forwardRulesShow = ref(false)
const settingStore = useSettingStore();
const {settings: setting} = storeToRefs(settingStore);
const editTitle = ref('')
@@ -345,11 +465,123 @@ const options = [
{label: '20s', value: 20}
]
onMounted(() => {
resendTokenForm.domain = settingStore.domainList[0];
loginOpacity.value = settingStore.settings.loginOpacity
const tgChatId = ref([])
const tgBotStatus = ref(0)
const tgBotToken = ref('')
const forwardEmail = ref([])
const forwardStatus = ref(0)
const ruleType = ref(0)
const ruleEmail = ref([])
settingQuery().then(settingData => {
setting.value = settingData
resendTokenForm.domain = setting.value.domainList[0]
loginOpacity.value = setting.value.loginOpacity
firstLoading.value = false
})
function openTgSetting() {
tgBotStatus.value = setting.value.tgBotStatus
tgBotToken.value = setting.value.tgBotToken
tgChatId.value = []
if (setting.value.tgChatId) {
const list = setting.value.tgChatId.split(',')
tgChatId.value.push(...list)
}
tgSettingShow.value = true
}
function openThirdEmailSetting() {
forwardEmail.value = []
forwardStatus.value = setting.value.forwardStatus
if (setting.value.forwardEmail) {
const list = setting.value.forwardEmail.split(',')
forwardEmail.value.push(...list)
}
thirdEmailShow.value = true
}
function openForwardRules() {
ruleType.value = setting.value.ruleType
ruleEmail.value = []
if (setting.value.ruleEmail) {
const list = setting.value.ruleEmail.split(',')
ruleEmail.value.push(...list)
}
forwardRulesShow.value = true
}
function emailAddTag(val) {
const emails = Array.from(new Set(
val.split(/[,]/).map(item => item.trim()).filter(item => item)
));
forwardEmail.value.splice(forwardEmail.value.length - 1, 1)
emails.forEach(email => {
if (isEmail(email) && !forwardEmail.value.includes(email)) {
forwardEmail.value.push(email)
}
})
}
function ruleEmailAddTag(val) {
const emails = Array.from(new Set(
val.split(/[,]/).map(item => item.trim()).filter(item => item)
));
ruleEmail.value.splice(ruleEmail.value.length - 1, 1)
emails.forEach(email => {
if (isEmail(email) && !ruleEmail.value.includes(email)) {
ruleEmail.value.push(email)
}
})
}
function addChatTag(val) {
const chatIds = Array.from(new Set(
val.split(/[,]/).map(item => item.trim()).filter(item => item)
));
tgChatId.value.splice(tgChatId.value.length - 1, 1)
chatIds.forEach(id => {
if (!isNaN(Number(id))) {
tgChatId.value.push(id)
}
})
}
function tgBotSave() {
const form = {
tgBotToken: tgBotToken.value,
tgBotStatus: tgBotStatus.value,
tgChatId: tgChatId.value + ''
}
editSetting(form)
}
function forwardEmailSave() {
const form = {
forwardStatus: forwardStatus.value,
forwardEmail: forwardEmail.value + ''
}
editSetting(form)
}
function ruleEmailSave() {
const form = {
ruleEmail: ruleEmail.value + '',
ruleType: ruleType.value
}
editSetting(form)
}
function doOpacityChange() {
const form = {}
form.loginOpacity = loginOpacity.value
@@ -500,6 +732,7 @@ function jump(href) {
function editSetting(settingForm, refreshStatus = true) {
if (settingLoading.value) return
settingLoading.value = true
settingSet(settingForm).then(() => {
settingLoading.value = false
ElMessage({
@@ -517,7 +750,11 @@ function editSetting(settingForm, refreshStatus = true) {
r2DomainShow.value = false
resendTokenFormShow.value = false
turnstileShow.value = false
}).catch(() => {
tgSettingShow.value = false
thirdEmailShow.value = false
forwardRulesShow.value = false
}).catch((e) => {
console.log(e)
loginOpacity.value = setting.value.loginOpacity
setting.value = {...setting.value, ...JSON.parse(backup)}
}).finally(() => {
@@ -530,11 +767,27 @@ function editSetting(settingForm, refreshStatus = true) {
.settings-container {
height: 100%;
overflow: hidden;
background: #FAFCFF;
background: #FAFCFF !important;
.loading {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
}
.scroll {
width: 100%;
min-height: 100%;
:deep(.el-scrollbar__view) {
height: 100%;
}
.scroll-body {
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
.card-grid {
@@ -577,6 +830,12 @@ function editSetting(settingForm, refreshStatus = true) {
overflow: hidden;
}
@media (min-width: 885px) {
.about {
height: 210px;
}
}
.card-title {
font-size: 15px;
font-weight: bold;
@@ -596,7 +855,6 @@ function editSetting(settingForm, refreshStatus = true) {
grid-template-columns: auto 1fr;
gap: 10px;
font-weight: bold;
> div:first-child {
display: flex;
align-items: center;
@@ -626,11 +884,48 @@ function editSetting(settingForm, refreshStatus = true) {
}
}
.dialog-footer {
display: flex;
justify-content: space-between;
}
:deep(.el-dialog) {
width: 400px !important;
@media (max-width: 440px) {
width: calc(100% - 40px) !important;
margin-right: 20px !important;
margin-left: 20px !important;
}
}
:deep(.cut-dialog.el-dialog) {
width: fit-content !important;
height: fit-content !important;
}
:deep(.forward-dialog.el-dialog) {
width: 500px !important;
@media (max-width: 540px) {
width: calc(100% - 40px) !important;
margin-right: 20px !important;
margin-left: 20px !important;
}
}
.forward-dialog {
.forward-head {
display: flex;
align-items: center;
.forward-set-title {
top: 1px;
position: relative;
font-size: 16px;
font-weight: bold;
}
}
}
.error-image {
background: #f5f7fa;
height: 100%;
@@ -654,7 +949,34 @@ function editSetting(settingForm, refreshStatus = true) {
.bot-verify {
display: grid;
grid-template-columns: 1fr auto;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
span {
display: flex;
align-items: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
min-width: 0;
}
.el-button {
width: 48px;
margin: 0 0 0 10px;
}
}
.forward-set-body {
display: flex;
flex-direction: column;
gap: 15px;
.el-switch {
align-self: end;
}
}
.forward {
span {
display: flex;
align-items: center;
@@ -763,4 +1085,10 @@ form .el-button {
:deep(.el-select__wrapper) {
min-height: 28px;
}
</style>
<style>
.el-popper.is-dark {
}
</style>