fix(frontend): persist generation in-flight key in sessionStorage (HMR/reload)

Made-with: Cursor
This commit is contained in:
hub-gif 2026-04-14 14:18:33 +08:00
parent a1b02e3ed7
commit fdf5901f76

View File

@ -1,10 +1,58 @@
import { ref } from 'vue'
const STORAGE_KEY = 'ma_generation_inflight'
const STORAGE_TS = 'ma_generation_inflight_ts'
/** 含 LLM 的重新生成可能较久;超时后视为未进行,避免按钮永久禁用 */
const TTL_MS = 45 * 60 * 1000
function readPersisted() {
if (typeof sessionStorage === 'undefined') return null
try {
const k = sessionStorage.getItem(STORAGE_KEY)
const ts = sessionStorage.getItem(STORAGE_TS)
if (!k || ts == null) return null
const t = Number(ts)
if (!Number.isFinite(t) || Date.now() - t > TTL_MS) {
sessionStorage.removeItem(STORAGE_KEY)
sessionStorage.removeItem(STORAGE_TS)
return null
}
return k
} catch {
return null
}
}
function writePersisted(k) {
if (typeof sessionStorage === 'undefined') return
try {
if (k) {
sessionStorage.setItem(STORAGE_KEY, k)
sessionStorage.setItem(STORAGE_TS, String(Date.now()))
} else {
sessionStorage.removeItem(STORAGE_KEY)
sessionStorage.removeItem(STORAGE_TS)
}
} catch {
/* 隐私模式 / 配额 */
}
}
/**
* 长耗时生成类 POST/GET 进行中标记模块级路由切换不丢
* 长耗时生成类 POST/GET 进行中标记
* 除模块级 ref 外写入 sessionStorage避免 Vite HMR / 整页刷新后丢失
* 从而出现切换页签后重新生成又可点的假象
*
* key 示例`strategy-draft:12``regenerate-report:12``preview-report:12`
*/
const inFlightKey = ref(null)
const inFlightKey = ref(readPersisted())
if (typeof window !== 'undefined') {
window.addEventListener('storage', (e) => {
if (e.key !== STORAGE_KEY && e.key !== STORAGE_TS) return
inFlightKey.value = readPersisted()
})
}
export function generationInFlightKey() {
return inFlightKey
@ -17,11 +65,13 @@ export function generationInFlightKey() {
*/
export async function withGenerationInFlight(key, fn) {
inFlightKey.value = key
writePersisted(key)
try {
return await fn()
} finally {
if (inFlightKey.value === key) {
inFlightKey.value = null
writePersisted(null)
}
}
}