Files
zkxw/web-admin/src/utils/menu-badge-polling.ts
T
zlwuandCursor 5dad1bb0e3 fix: 协议子资源单事务保存,并补齐样本编码/OA/质检等近期能力
锁定缴费校验失败时整单回滚,避免样本半成功落库;前端禁止删除锁定缴费样本,改码走更正编码。同步落地样本更正、采集微信通知、OA提及未读、细胞产品套餐与相关迁移文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-26 11:02:25 +08:00

84 lines
2.1 KiB
TypeScript

import { refreshOaMenuBadges } from './oa-menu-badge'
import { refreshQcMenuBadges } from './qc-menu-badge'
import { refreshProductionMenuBadges } from './production-menu-badge'
export const MENU_BADGE_POLL_INTERVAL_MS = 60_000
let timerId: ReturnType<typeof setInterval> | null = null
let visibilityBound = false
let inFlight = false
let started = false
export function isMenuBadgePollingActive(): boolean {
return started
}
export async function refreshAllMenuBadges(): Promise<void> {
if (inFlight) return
inFlight = true
try {
await Promise.allSettled([
refreshOaMenuBadges(),
refreshQcMenuBadges(),
refreshProductionMenuBadges()
])
} finally {
inFlight = false
}
}
function onVisibilityChange(): void {
if (typeof document === 'undefined') return
if (document.hidden) {
if (timerId != null) {
clearInterval(timerId)
timerId = null
}
return
}
// 恢复可见:立即补刷,再重启 interval
void refreshAllMenuBadges()
if (started && timerId == null) {
timerId = setInterval(() => {
void refreshAllMenuBadges()
}, MENU_BADGE_POLL_INTERVAL_MS)
}
}
function bindVisibility(): void {
if (visibilityBound || typeof document === 'undefined') return
document.addEventListener('visibilitychange', onVisibilityChange)
visibilityBound = true
}
function unbindVisibility(): void {
if (!visibilityBound || typeof document === 'undefined') return
document.removeEventListener('visibilitychange', onVisibilityChange)
visibilityBound = false
}
/** 幂等:已启动则忽略。启动时立即刷一轮,再按 60s 轮询。 */
export function startMenuBadgePolling(): void {
if (started) return
started = true
bindVisibility()
void refreshAllMenuBadges()
if (typeof document !== 'undefined' && document.hidden) {
// 隐藏态不启 timer,等可见时 onVisibilityChange 重启
return
}
timerId = setInterval(() => {
void refreshAllMenuBadges()
}, MENU_BADGE_POLL_INTERVAL_MS)
}
export function stopMenuBadgePolling(): void {
started = false
if (timerId != null) {
clearInterval(timerId)
timerId = null
}
unbindVisibility()
inFlight = false
}