From 0ee5ed4e101f083361801e3faf9822922e8f0360 Mon Sep 17 00:00:00 2001 From: smail Date: Mon, 14 Sep 2026 01:02:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(email):=20=E5=8F=91=E4=BB=B6=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E5=89=8D=E6=96=B0=E5=A2=9E=E5=88=B7=E6=96=B0=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E5=B9=B6=E6=94=AF=E6=8C=81=E6=89=8B=E5=8A=A8=E5=8D=B3?= =?UTF-8?q?=E6=97=B6=E5=88=B7=E6=96=B0=E4=B8=8E=E7=99=BB=E5=BD=95=E6=80=81?= =?UTF-8?q?=E8=87=AA=E9=80=82=E5=BA=94=E5=AE=9A=E6=97=B6=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/i18n/i18n.js | 1 + frontend/src/views/List/List.css | 9 ++++ frontend/src/views/List/List.js | 75 +++++++++++++++++++++++++++++--- frontend/src/views/List/List.vue | 9 +++- 4 files changed, 85 insertions(+), 9 deletions(-) diff --git a/frontend/src/i18n/i18n.js b/frontend/src/i18n/i18n.js index 79a2c35..152ff0c 100644 --- a/frontend/src/i18n/i18n.js +++ b/frontend/src/i18n/i18n.js @@ -11,6 +11,7 @@ const lang = { "plugin_settings": "插件配置", "lang": "zhCn", "submit": "提交", + "refresh": "刷新", "compose": "发件", "new": "新", "account": "账号", diff --git a/frontend/src/views/List/List.css b/frontend/src/views/List/List.css index ebb41c9..e1991e2 100644 --- a/frontend/src/views/List/List.css +++ b/frontend/src/views/List/List.css @@ -66,6 +66,15 @@ transform: translateY(-1px); } +.refresh-btn { + margin-left: 4px; +} + +.refresh-btn:hover .el-icon { + transform: rotate(90deg); + transition: transform 0.3s ease-in-out; +} + .compose-btn { border-radius: 999px; font-weight: 600; diff --git a/frontend/src/views/List/List.js b/frontend/src/views/List/List.js index c80bc5a..19297c8 100644 --- a/frontend/src/views/List/List.js +++ b/frontend/src/views/List/List.js @@ -2,13 +2,14 @@ import './List.js' import {EpArrowDownBold} from "vue-icons-plus/ep"; -import {Delete, View, Folder, EditPen, Warning, CircleCheck, Switch, Check} from "@element-plus/icons-vue"; +import {Delete, View, Folder, EditPen, Warning, CircleCheck, Switch, Check, Refresh} from "@element-plus/icons-vue"; import {useRouter} from 'vue-router' -import {ref, watch, computed} from 'vue' +import {ref, watch, computed, onMounted, onUnmounted} from 'vue' import useGroupStore from '../../stores/group' +import {useGlobalStatusStore} from '../../stores/useGlobalStatusStore' import lang from '../../i18n/i18n'; @@ -20,8 +21,11 @@ export function usePage() { const router = useRouter(); const groupStore = useGroupStore() + const globalStatus = useGlobalStatusStore() const groupList = ref([]) + const isRefreshing = ref(false) + let refreshTimer = null const taskTableDataRef = ref(null) @@ -58,11 +62,23 @@ export function usePage() { const totalPage = ref(0) - const updateList = function () { - http.post("/api/v1/email/list", {tag: tag, page_size: 15}).then(res => { + const updateList = async function (silent = false) { + if (!silent) { + isRefreshing.value = true + } + try { + const res = await http.post("/api/v1/email/list", {tag: tag, page_size: 15}) data.value = res.data.list || [] totalPage.value = res.data.total_page || 0 - }) + } catch (err) { + if (!silent) { + ElMessage.error(err?.message || '获取邮件列表失败') + } + } finally { + if (!silent) { + isRefreshing.value = false + } + } } const updateGroupList = async function () { @@ -81,6 +97,48 @@ export function usePage() { updateList() updateGroupList() + + // 定时刷新逻辑:已登录 60s,未登录 300s + const getRefreshInterval = () => { + return globalStatus.isLogin ? 60000 : 300000 + } + + const startAutoRefreshTimer = () => { + stopAutoRefreshTimer() + const interval = getRefreshInterval() + refreshTimer = setInterval(() => { + updateList(true) + updateGroupList() + }, interval) + } + + const stopAutoRefreshTimer = () => { + if (refreshTimer) { + clearInterval(refreshTimer) + refreshTimer = null + } + } + + const manualRefresh = async () => { + await Promise.all([ + updateList(false), + updateGroupList() + ]) + ElMessage.success('已刷新') + startAutoRefreshTimer() + } + + watch(() => globalStatus.isLogin, () => { + startAutoRefreshTimer() + }) + + onMounted(() => { + startAutoRefreshTimer() + }) + + onUnmounted(() => { + stopAutoRefreshTimer() + }) const rowClick = function (row) { router.push("/detail/" + row.id) @@ -259,7 +317,9 @@ export function usePage() { trustSender, showError, errorDialogVisible, - currentErrorMsg + currentErrorMsg, + isRefreshing, + manualRefresh } } @@ -272,5 +332,6 @@ export { EpArrowDownBold, EditPen, Warning, - Check + Check, + Refresh } diff --git a/frontend/src/views/List/List.vue b/frontend/src/views/List/List.vue index dc4c51b..f4173b0 100644 --- a/frontend/src/views/List/List.vue +++ b/frontend/src/views/List/List.vue @@ -32,6 +32,9 @@ + + {{ lang.refresh }} + {{ lang.compose }} @@ -121,7 +124,7 @@