fix: 修复公告关闭功能 - 当次关闭与永久关闭区分

问题:不管选择"当次关闭"还是"永久关闭",都会永久关闭公告

修复:
- 当次关闭:使用 sessionStorage + pageToken
  - pageToken 基于 performance.timeOrigin 生成
  - 刷新页面后 token 变化,公告重新显示
- 永久关闭:使用 localStorage
  - 持久化存储,刷新/重开后不再显示

修改文件:
- app-frontend/src/layouts/AppLayout.vue
- templates/index.html

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-27 21:51:28 +08:00
parent 70e09c83a8
commit 2d98ab66a3
16 changed files with 168 additions and 97 deletions

View File

@@ -1055,24 +1055,39 @@
});
}
let currentAnnouncementId = null;
let currentAnnouncementId = null;
const announcementPageToken = (() => {
try {
const timeOrigin = window.performance?.timeOrigin;
if (typeof timeOrigin === 'number' && Number.isFinite(timeOrigin)) return String(timeOrigin);
} catch (e) {
// ignore
}
return String(Date.now());
})();
async function checkAnnouncement() {
try {
const response = await fetch('/api/announcements/active');
if (!response.ok) return;
async function checkAnnouncement() {
try {
const response = await fetch('/api/announcements/active');
if (!response.ok) return;
const data = await response.json();
const announcement = data?.announcement;
if (!announcement || !announcement.id) return;
const sessionKey = `announcement_closed_${announcement.id}`;
try {
if (sessionStorage.getItem(sessionKey)) return;
} catch (e) {
// ignore
}
const permanentKey = `announcement_closed_${announcement.id}`;
const onceKey = `announcement_closed_once_${announcement.id}`;
try {
if (localStorage.getItem(permanentKey) === '1') return;
} catch (e) {
// ignore
}
try {
if (sessionStorage.getItem(onceKey) === announcementPageToken) return;
} catch (e) {
// ignore
}
currentAnnouncementId = announcement.id;
currentAnnouncementId = announcement.id;
const titleEl = document.getElementById('announcementModalTitle');
const contentEl = document.getElementById('announcementModalContent');
if (titleEl) titleEl.textContent = announcement.title || '系统公告';
@@ -1083,29 +1098,34 @@
}
}
function closeAnnouncementOnce() {
if (currentAnnouncementId) {
try {
sessionStorage.setItem(`announcement_closed_${currentAnnouncementId}`, '1');
} catch (e) {
// ignore
}
}
closeModal('announcementModal');
}
function closeAnnouncementOnce() {
if (currentAnnouncementId) {
try {
sessionStorage.setItem(`announcement_closed_once_${currentAnnouncementId}`, announcementPageToken);
} catch (e) {
// ignore
}
}
closeModal('announcementModal');
}
async function dismissAnnouncementPermanently() {
if (!currentAnnouncementId) {
closeModal('announcementModal');
return;
}
try {
await fetch(`/api/announcements/${currentAnnouncementId}/dismiss`, { method: 'POST' });
} catch (e) {
// ignore
}
closeAnnouncementOnce();
}
async function dismissAnnouncementPermanently() {
if (!currentAnnouncementId) {
closeModal('announcementModal');
return;
}
try {
localStorage.setItem(`announcement_closed_${currentAnnouncementId}`, '1');
} catch (e) {
// ignore
}
try {
await fetch(`/api/announcements/${currentAnnouncementId}/dismiss`, { method: 'POST' });
} catch (e) {
// ignore
}
closeAnnouncementOnce();
}
document.addEventListener('DOMContentLoaded', function() {
initTabs();
loadVipStatus();