fix(admin): 修复退出登录 store 重置崩溃及若干体验问题

- notify store 补充 $reset, 修复退出登录时 setup 语法 store 无 $reset 导致的崩溃
- user-dropdown 移除无用的"问题 & 帮助"菜单项及对应 qa 国际化键(zh-CN/en-US)
- formatDate 对空值/无效日期静默返回空字符串, 不再向控制台报错
- NoticeEdit 抽屉 width 改为 size 属性
This commit is contained in:
DaxPay Dev
2026-06-24 22:00:17 +08:00
parent f50ff58799
commit 84ba62e492
6 changed files with 26 additions and 31 deletions

View File

@@ -1,7 +1,8 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { NotifyUserApi, type NotifyNoticeBrief } from '#/api/system/notify/user.api';
import { defineStore } from 'pinia';
import { type NotifyNoticeBrief, NotifyUserApi } from '#/api/system/notify/user.api';
/**
* 站内通知 store(当前登录用户视角)
@@ -64,7 +65,7 @@ export const useNotifyStore = defineStore('notify', () => {
}
/** SSE 连接实例(模块级, 避免响应式开销) */
let eventSource: null | EventSource = null;
let eventSource: EventSource | null = null;
/**
* 建立 SSE 实时推送连接
@@ -80,7 +81,7 @@ export const useNotifyStore = defineStore('notify', () => {
withCredentials: true,
});
// 收到推送即刷新未读数与铃铛列表
eventSource.onmessage = () => {
eventSource.onmessage! = () => {
refresh().catch(() => {});
};
} catch {
@@ -96,11 +97,19 @@ export const useNotifyStore = defineStore('notify', () => {
eventSource = null;
}
/**
* 重置 store(setup 语法需手动实现 $reset, 退出登录时由 resetAllStores 调用)
*/
function $reset() {
list.value = [];
unreadCount.value = 0;
disconnectSSE();
}
return {
$reset,
connectSSE,
disconnectSSE,
fetchList,
fetchUnreadCount,
ignore,
list,
markAllRead,

View File

@@ -132,7 +132,7 @@
<a-drawer
:open="visible"
:title="title"
width="85%"
size="85%"
:mask-closable="showable"
wrap-class-name="notice-drawer"
@close="closeWithConfirm"

View File

@@ -2,7 +2,7 @@
import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';
import { BookOpenText, CircleHelp, LockKeyhole, LogOut, UserRoundPen } from '@vben/icons';
import { BookOpenText, LockKeyhole, LogOut, UserRoundPen } from '@vben/icons';
import { $t } from '@vben/locales';
import { preferences, usePreferences } from '@vben/preferences';
import { useAccessStore } from '@vben/stores';
@@ -25,7 +25,7 @@
const emit = defineEmits<{ logout: [] }>();
// 项目文档地址(文档 / 问题与帮助均跳转至此)
// 项目文档地址(文档跳转至此)
const DOC_URL = 'https://doc.daxpay.cn';
const router = useRouter();
@@ -55,11 +55,6 @@
openWindow(DOC_URL, { target: '_blank' });
}
/** 打开问题 & 帮助 */
function openIssue() {
openWindow(DOC_URL, { target: '_blank' });
}
/** 打开锁屏密码弹窗 */
function openLockModal() {
lockModalOpen.value = true;
@@ -89,10 +84,6 @@
openDocs();
break;
}
case 'issue': {
openIssue();
break;
}
case 'lock': {
openLockModal();
break;
@@ -150,13 +141,6 @@
<span>{{ $t('ui.widgets.document') }}</span>
</div>
</a-menu-item>
<!-- 问题 & 帮助 -->
<a-menu-item key="issue">
<div class="flex items-center">
<CircleHelp class="mr-2 size-4" />
<span>{{ $t('ui.widgets.qa') }}</span>
</div>
</a-menu-item>
<!-- 锁定屏幕 -->
<template v-if="enableLockScreen">
<a-menu-divider />

View File

@@ -28,6 +28,10 @@ type Format =
* @returns 格式化后的日期字符串
*/
export function formatDate(time?: FormatDate, format: Format = 'YYYY-MM-DD') {
// 空值 (null、undefined、空字符串) 直接返回空字符串, 不做格式化也不报错
if (time === null || time === undefined || time === '') {
return '';
}
try {
let date: dayjs.Dayjs;
// 已经是 dayjs 对象, 直接复用
@@ -40,14 +44,14 @@ export function formatDate(time?: FormatDate, format: Format = 'YYYY-MM-DD') {
} else {
date = dayjs(time);
}
// 日期无效时抛出异常, 进入 catch 返回原始值
// 日期无效时静默返回空字符串, 不在控制台报错
if (!date.isValid()) {
throw new Error('Invalid date');
return '';
}
// 按用户时区转换后格式化
return date.tz().format(format);
} catch (error) {
console.error(`Error formatting date: ${error}`);
} catch {
// 解析异常时返回原始值的字符串形式, 不在控制台报错
return String(time ?? '');
}
}

View File

@@ -84,7 +84,6 @@
},
"widgets": {
"document": "Documentation",
"qa": "Q&A",
"setting": "Settings",
"logoutTip": "Do you want to logout?",
"viewAll": "View All Messages",

View File

@@ -84,7 +84,6 @@
},
"widgets": {
"document": "使用文档",
"qa": "问题 & 帮助",
"setting": "设置",
"logoutTip": "是否退出登录?",
"viewAll": "查看所有消息",