chore(admin): final polish and QA doc

This commit is contained in:
2025-12-13 21:46:34 +08:00
parent 49bc8b83b1
commit 85a60009f3
27 changed files with 145 additions and 75 deletions

View File

@@ -1,6 +1,17 @@
import axios from 'axios'
import { ElMessage } from 'element-plus'
let lastToastKey = ''
let lastToastAt = 0
function toastErrorOnce(key, message, minIntervalMs = 1500) {
const now = Date.now()
if (key === lastToastKey && now - lastToastAt < minIntervalMs) return
lastToastKey = key
lastToastAt = now
ElMessage.error(message)
}
export const api = axios.create({
baseURL: '/yuyx/api',
timeout: 30_000,
@@ -15,16 +26,15 @@ api.interceptors.response.use(
const message = payload?.error || payload?.message || error?.message || '请求失败'
if (status === 403) {
ElMessage.error(message || '需要管理员权限')
toastErrorOnce('403', message || '需要管理员权限', 5000)
} else if (status) {
ElMessage.error(message)
toastErrorOnce(`http:${status}:${message}`, message)
} else if (error?.code === 'ECONNABORTED') {
ElMessage.error('请求超时')
toastErrorOnce('timeout', '请求超时', 3000)
} else {
ElMessage.error(message)
toastErrorOnce(`net:${message}`, message, 3000)
}
return Promise.reject(error)
},
)

View File

@@ -318,6 +318,22 @@ async function go(path) {
}
@media (max-width: 768px) {
.layout-header {
flex-wrap: wrap;
height: auto;
padding-top: 10px;
padding-bottom: 10px;
}
.header-right {
width: 100%;
justify-content: flex-end;
}
.admin-name .app-muted {
display: none;
}
.layout-main {
padding: 12px;
}

View File

@@ -1,5 +1,5 @@
<script setup>
import { computed, onMounted, reactive, ref } from 'vue'
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { cleanupEmailLogs, fetchEmailLogs, fetchEmailSettings, fetchEmailStats, updateEmailSettings } from '../api/email'
@@ -73,6 +73,11 @@ function scheduleSaveEmailSettings() {
saveTimer = window.setTimeout(saveEmailSettings, 300)
}
onBeforeUnmount(() => {
if (saveTimer) window.clearTimeout(saveTimer)
saveTimer = null
})
// ========== SMTP 配置 ==========
const smtpLoading = ref(false)
const smtpConfigs = ref([])
@@ -596,7 +601,11 @@ onMounted(refreshAll)
</div>
</el-card>
<el-dialog v-model="smtpDialogOpen" :title="smtpEditMode ? '编辑SMTP配置' : '添加SMTP配置'" width="560px">
<el-dialog
v-model="smtpDialogOpen"
:title="smtpEditMode ? '编辑SMTP配置' : '添加SMTP配置'"
width="min(560px, 92vw)"
>
<el-form label-width="120px">
<el-form-item label="名称">
<el-input v-model="smtpForm.name" />

View File

@@ -415,6 +415,16 @@ onBeforeUnmount(() => {
color: #f59e0b;
}
@media (max-width: 768px) {
.task-item {
flex-direction: column;
}
.task-right {
align-self: flex-end;
}
}
.stat-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));

View File

@@ -49,3 +49,32 @@ a {
.app-muted {
color: var(--app-muted);
}
@media (max-width: 768px) {
.app-page-title {
flex-wrap: wrap;
align-items: flex-start;
}
.el-dialog {
max-width: 92vw;
}
.el-form-item {
flex-direction: column;
align-items: stretch;
}
.el-form-item__label {
width: auto !important;
justify-content: flex-start !important;
padding: 0 0 6px !important;
line-height: 1.4;
text-align: left !important;
}
.el-form-item__content {
margin-left: 0 !important;
width: 100%;
}
}