Files
order_site/apps/frontend/src/utils/announcement-ack.ts
T

61 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 打手端公告弹窗的「已确认」记忆。
*
* 后台公告只有一条全局配置(`worker_announcement = { enabled, content }`),没有公告 ID,
* 因此这里用**内容指纹**充当版本号:只要运营改了公告正文,指纹就变,打手端会重新弹一次。
* 确认记录存在 localStorage(方案 B:服务端不落库),换设备或清缓存后会再弹一次。
*/
const ANNOUNCEMENT_ACK_STORAGE_KEY = 'order-site-worker-announcement-ack'
type AnnouncementPopupState = {
enabled?: boolean
content?: string
/** 本地已确认过的公告版本(来自 localStorage) */
acknowledgedVersion?: string
}
/** 公告正文的内容指纹(FNV-1a 32 位),空内容返回空串表示「没有可确认的公告」。 */
export function resolveAnnouncementVersion(content: string): string {
const normalized = String(content || '').trim()
if (!normalized) return ''
let hash = 0x811c9dc5
for (let index = 0; index < normalized.length; index += 1) {
hash ^= normalized.charCodeAt(index)
hash = Math.imul(hash, 0x01000193) >>> 0
}
return `v1-${hash.toString(16).padStart(8, '0')}`
}
/**
* 是否需要弹窗:公告开启 + 有正文 + 当前版本还没被这台设备确认过。
* 已确认过的版本不再弹;运营改了正文(版本变化)后会重新弹。
*/
export function shouldShowAnnouncementPopup(state: AnnouncementPopupState): boolean {
if (state.enabled !== true) return false
const version = resolveAnnouncementVersion(state.content || '')
if (!version) return false
return state.acknowledgedVersion !== version
}
/** 读取本机已确认的公告版本(隐私模式/禁用存储时返回空串,页面照常可用)。 */
export function readAnnouncementAck(): string {
try {
if (typeof window === 'undefined') return ''
return window.localStorage.getItem(ANNOUNCEMENT_ACK_STORAGE_KEY) || ''
} catch {
return ''
}
}
/** 记录本机已确认的公告版本。 */
export function writeAnnouncementAck(version: string): void {
if (!version) return
try {
if (typeof window === 'undefined') return
window.localStorage.setItem(ANNOUNCEMENT_ACK_STORAGE_KEY, version)
} catch {
// 存储不可用(隐私模式/配额满)时忽略,下一次打开会再弹一次。
}
}