修复全部邮件权限无效问题

This commit is contained in:
eoao
2025-08-22 01:05:00 +08:00
parent ff8ba81661
commit 8cd75868bc
10 changed files with 222 additions and 196 deletions

View File

@@ -1,97 +1,105 @@
<!doctype html> <!doctype html>
<html lang="en" class="dark"> <html lang="en" class="dark">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title></title> <title></title>
<link rel="icon" href="./src/assets/favicon.svg" type="image/svg+xml"> <link rel="icon" href="./src/assets/favicon.svg" type="image/svg+xml">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head> </head>
<body> <body>
<div id="loading-first"> <div id="loading-first">
<div class="loading-icon"> <div class="loading-icon">
<svg class="circular" viewBox="0 0 20 20"> <svg class="circular" viewBox="0 0 20 20">
<g class="loading-path"> <g class="loading-path">
<circle r="3.375" class="dot1" rx="0" ry="0" /> <circle r="3.375" class="dot1" rx="0" ry="0"/>
<circle r="3.375" class="dot2" rx="0" ry="0" /> <circle r="3.375" class="dot2" rx="0" ry="0"/>
<circle r="3.375" class="dot4" rx="0" ry="0" /> <circle r="3.375" class="dot4" rx="0" ry="0"/>
<circle r="3.375" class="dot3" rx="0" ry="0" /> <circle r="3.375" class="dot3" rx="0" ry="0"/>
</g> </g>
</svg> </svg>
</div> </div>
</div> </div>
<div id="app"></div> <div id="app"></div>
<script>
const uiStoreStr = localStorage.getItem('ui')
if (uiStoreStr) {
const uiStore = JSON.parse(uiStoreStr)
const doc = document.querySelector('#loading-first')
doc.style.background = uiStore.dark ? '#141414' : '#FFFFFF'
}
</script>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>
</body> </body>
</html> </html>
<style> <style>
#loading-first {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
z-index: 500;
}
.loading-icon { #loading-first {
display: inline-flex; position: fixed;
align-items: center; left: 0;
justify-content: center; top: 0;
font-size: 30px; height: 100%;
} width: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 500;
}
.circular { .loading-icon {
height: 30px; display: inline-flex;
width: 30px; align-items: center;
animation: loading-rotate 1s linear infinite; justify-content: center;
} font-size: 30px;
}
.loading-path .dot1 { .circular {
transform: translate(3.75px, 3.75px); height: 30px;
fill: #409EFF; width: 30px;
animation: custom-spin-move 1s infinite linear alternate; animation: loading-rotate 1s linear infinite;
opacity: 0.3; }
}
.loading-path .dot2 { .loading-path .dot1 {
transform: translate(calc(100% - 3.75px), 3.75px); transform: translate(3.75px, 3.75px);
fill: #409EFF; fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate; animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3; opacity: 0.3;
animation-delay: 0.4s; }
}
.loading-path .dot3 { .loading-path .dot2 {
transform: translate(3.75px, calc(100% - 3.75px)); transform: translate(calc(100% - 3.75px), 3.75px);
fill: #409EFF; fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate; animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3; opacity: 0.3;
animation-delay: 1.2s; animation-delay: 0.4s;
} }
.loading-path .dot4 { .loading-path .dot3 {
transform: translate(calc(100% - 3.75px), calc(100% - 3.75px)); transform: translate(3.75px, calc(100% - 3.75px));
fill: #409EFF; fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate; animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3; opacity: 0.3;
animation-delay: 0.8s; animation-delay: 1.2s;
} }
@keyframes loading-rotate { .loading-path .dot4 {
to { transform: translate(calc(100% - 3.75px), calc(100% - 3.75px));
transform: rotate(360deg); fill: #409EFF;
} animation: custom-spin-move 1s infinite linear alternate;
} opacity: 0.3;
animation-delay: 0.8s;
}
@keyframes custom-spin-move { @keyframes loading-rotate {
to { to {
opacity: 1; transform: rotate(360deg);
}
} }
</style> }
@keyframes custom-spin-move {
to {
opacity: 1;
}
}
</style>

View File

@@ -498,7 +498,6 @@ path[fill="#ffdda1"] {
.account { .account {
font-weight: 600; font-weight: 600;
margin-bottom: 20px; margin-bottom: 20px;
color: #333;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;

View File

@@ -31,7 +31,7 @@
<Icon icon="fluent:settings-48-regular" width="20" height="20" /> <Icon icon="fluent:settings-48-regular" width="20" height="20" />
<span class="menu-name" style="margin-left: 21px">{{$t('settings')}}</span> <span class="menu-name" style="margin-left: 21px">{{$t('settings')}}</span>
</el-menu-item> </el-menu-item>
<div class="manage-title" v-perm="['user:query','role:query','setting:query','analysis:query','reg-key:query']"> <div class="manage-title" v-perm="['all-email:query','user:query','role:query','setting:query','analysis:query','reg-key:query']">
<div>{{$t('manage')}}</div> <div>{{$t('manage')}}</div>
</div> </div>
<el-menu-item @click="router.push({name: 'analysis'})" index="analysis" v-perm="'analysis:query'" <el-menu-item @click="router.push({name: 'analysis'})" index="analysis" v-perm="'analysis:query'"

View File

@@ -252,12 +252,6 @@ function formatName(email) {
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.breadcrumb-item {
font-weight: bold;
font-size: 14px;
white-space: nowrap;
}
:deep(.el-popper.is-pure) { :deep(.el-popper.is-pure) {
border-radius: 6px; border-radius: 6px;
} }
@@ -357,7 +351,7 @@ function formatName(email) {
display: grid; display: grid;
height: 100%; height: 100%;
gap: 10px; gap: 10px;
grid-template-columns: auto auto 1fr; grid-template-columns: 1fr auto auto;
} }
.header.not-send { .header.not-send {
@@ -385,7 +379,7 @@ function formatName(email) {
.writer-text { .writer-text {
margin-left: 15px; margin-left: 15px;
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;;
} }
} }
} }
@@ -394,6 +388,16 @@ function formatName(email) {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
height: 100%; height: 100%;
min-width: 0;
}
.breadcrumb-item {
font-weight: bold;
font-size: 14px;
color: var(--el-text-color-primary);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} }
.toolbar { .toolbar {

View File

@@ -347,18 +347,20 @@
</div> </div>
<div class="concerning-item"> <div class="concerning-item">
<span>{{ $t('community') }} : </span> <span>{{ $t('community') }} : </span>
<el-button @click="jump('https://github.com/eoao/cloud-mail')"> <div class="community">
Github <el-button @click="jump('https://github.com/eoao/cloud-mail')">
<template #icon> Github
<Icon icon="codicon:github-inverted" width="22" height="22"/> <template #icon>
</template> <Icon icon="codicon:github-inverted" width="22" height="22"/>
</el-button> </template>
<el-button @click="jump('https://t.me/cloud_mail_tg')"> </el-button>
Telegram <el-button @click="jump('https://t.me/cloud_mail_tg')">
<template #icon> Telegram
<Icon icon="logos:telegram" width="30" height="30"/> <template #icon>
</template> <Icon icon="logos:telegram" width="30" height="30"/>
</el-button> </template>
</el-button>
</div>
</div> </div>
<div class="concerning-item"> <div class="concerning-item">
<span>{{ $t('support') }} : </span> <span>{{ $t('support') }} : </span>
@@ -1499,10 +1501,14 @@ function editSetting(settingForm, refreshStatus = true) {
display: flex; display: flex;
align-items: center; align-items: center;
.community {
display: flex;
row-gap: 10px;
flex-wrap: wrap;
}
:deep(.el-button) { :deep(.el-button) {
padding: 0 10px; padding: 0 10px;
font-weight: normal; font-weight: normal;
i { i {
font-size: 22px; font-size: 22px;
} }
@@ -1511,6 +1517,7 @@ function editSetting(settingForm, refreshStatus = true) {
> span:first-child { > span:first-child {
font-weight: normal; font-weight: normal;
padding-right: 20px; padding-right: 20px;
white-space: nowrap;
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,98 +1,106 @@
<!doctype html> <!doctype html>
<html lang="en" class="dark"> <html lang="en" class="dark">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title></title> <title></title>
<link rel="icon" href="/assets/favicon-C5dAZutX.svg" type="image/svg+xml"> <link rel="icon" href="/assets/favicon-C5dAZutX.svg" type="image/svg+xml">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script type="module" crossorigin src="/assets/index-Dst_pPIV.js"></script> <script type="module" crossorigin src="/assets/index-B5E7LhwJ.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CRd5bUNG.css"> <link rel="stylesheet" crossorigin href="/assets/index-Bhyg3tQ_.css">
</head> </head>
<body> <body>
<div id="loading-first"> <div id="loading-first">
<div class="loading-icon"> <div class="loading-icon">
<svg class="circular" viewBox="0 0 20 20"> <svg class="circular" viewBox="0 0 20 20">
<g class="loading-path"> <g class="loading-path">
<circle r="3.375" class="dot1" rx="0" ry="0" /> <circle r="3.375" class="dot1" rx="0" ry="0"/>
<circle r="3.375" class="dot2" rx="0" ry="0" /> <circle r="3.375" class="dot2" rx="0" ry="0"/>
<circle r="3.375" class="dot4" rx="0" ry="0" /> <circle r="3.375" class="dot4" rx="0" ry="0"/>
<circle r="3.375" class="dot3" rx="0" ry="0" /> <circle r="3.375" class="dot3" rx="0" ry="0"/>
</g> </g>
</svg> </svg>
</div> </div>
</div> </div>
<div id="app"></div> <div id="app"></div>
<script>
const uiStoreStr = localStorage.getItem('ui')
if (uiStoreStr) {
const uiStore = JSON.parse(uiStoreStr)
const doc = document.querySelector('#loading-first')
doc.style.background = uiStore.dark ? '#141414' : '#FFFFFF'
}
</script>
</body> </body>
</html> </html>
<style>
#loading-first {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
z-index: 500;
<style> <style>
.loading-icon { #loading-first {
display: inline-flex; position: fixed;
align-items: center; left: 0;
justify-content: center; top: 0;
font-size: 30px; height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 500;
} }
.circular { .loading-icon {
height: 30px; display: inline-flex;
width: 30px; align-items: center;
animation: loading-rotate 1s linear infinite; justify-content: center;
font-size: 30px;
} }
.loading-path .dot1 { .circular {
transform: translate(3.75px, 3.75px); height: 30px;
fill: #409EFF; width: 30px;
animation: custom-spin-move 1s infinite linear alternate; animation: loading-rotate 1s linear infinite;
opacity: 0.3;
} }
.loading-path .dot2 { .loading-path .dot1 {
transform: translate(calc(100% - 3.75px), 3.75px); transform: translate(3.75px, 3.75px);
fill: #409EFF; fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate; animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3; opacity: 0.3;
animation-delay: 0.4s;
} }
.loading-path .dot3 { .loading-path .dot2 {
transform: translate(3.75px, calc(100% - 3.75px)); transform: translate(calc(100% - 3.75px), 3.75px);
fill: #409EFF; fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate; animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3; opacity: 0.3;
animation-delay: 1.2s; animation-delay: 0.4s;
} }
.loading-path .dot4 { .loading-path .dot3 {
transform: translate(calc(100% - 3.75px), calc(100% - 3.75px)); transform: translate(3.75px, calc(100% - 3.75px));
fill: #409EFF; fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate; animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3; opacity: 0.3;
animation-delay: 0.8s; animation-delay: 1.2s;
} }
@keyframes loading-rotate { .loading-path .dot4 {
to { transform: translate(calc(100% - 3.75px), calc(100% - 3.75px));
transform: rotate(360deg); fill: #409EFF;
} animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 0.8s;
} }
@keyframes custom-spin-move { @keyframes loading-rotate {
to { to {
opacity: 1;
transform: rotate(360deg); transform: rotate(360deg);
}
}
@keyframes custom-spin-move {
to {
opacity: 1;
}
} }

View File

@@ -95,8 +95,8 @@ const init = {
}, },
async v1_5DB(c) { async v1_5DB(c) {
await c.env.db.prepare(`UPDATE perm SET perm_key = 'sys-email:list' WHERE perm_key = 'all-email:list'`).run(); await c.env.db.prepare(`UPDATE perm SET perm_key = 'all-email:query' WHERE perm_key = 'sys-email:query'`).run();
await c.env.db.prepare(`UPDATE perm SET perm_key = 'sys-email:delete' WHERE perm_key = 'all-email:delete'`).run(); await c.env.db.prepare(`UPDATE perm SET perm_key = 'all-email:delete' WHERE perm_key = 'sys-email:delete'`).run();
try { try {
await c.env.db.prepare(`ALTER TABLE role ADD COLUMN avail_domain TEXT NOT NULL DEFAULT ''`).run(); await c.env.db.prepare(`ALTER TABLE role ADD COLUMN avail_domain TEXT NOT NULL DEFAULT ''`).run();
} catch (e) { } catch (e) {