优化: 审批超时倒计时(60s变红)+分离窗口监听核验

This commit is contained in:
lxy
2026-08-15 18:46:13 +08:00
parent 871416637a
commit 13ecd7eba4
7 changed files with 64 additions and 10 deletions
+26 -7
View File
@@ -138,8 +138,15 @@ function getApprovalTimeoutMs(): number {
return raw
}
/** toolCallId → 审批超时计时器 */
const _approvalTimers = new Map<string, ReturnType<typeof setTimeout>>()
/** toolCallId → 审批超时计时器 + 起点信息(startedAt/timeoutMs 供前端到期倒计时读剩余) */
interface ApprovalTimerInfo {
timer: ReturnType<typeof setTimeout>
/** 计时器启动时刻(ms)——即本笔审批超时窗口的真实起点 */
startedAt: number
/** 本计时器生效的超时阈值(ms) */
timeoutMs: number
}
const _approvalTimers = new Map<string, ApprovalTimerInfo>()
/**
* 启动审批超时计时器(幂等:同 id 重复启动不重建)。
@@ -176,21 +183,33 @@ export function startApprovalTimer(
timestamp: Date.now(),
})
}, timeoutMs)
_approvalTimers.set(toolCallId, timer)
_approvalTimers.set(toolCallId, { timer, startedAt: Date.now(), timeoutMs })
}
/**
* 取某审批距前端自动拒绝的剩余毫秒。
* 审批超时是前端本计时器驱动的(到点才调 IPC 拒绝),故剩余值与实际拒绝时刻精确对齐,
* 优于后端 created_at(不序列化透传)或 ToolCard 本地到达时间的近似。
* 返回 null = 无活跃计时器(未挂起/已到期/用户配置不限时),调用方应回退其他展示。
*/
export function getApprovalRemainingMs(toolCallId: string): number | null {
const info = _approvalTimers.get(toolCallId)
if (!info) return null
return info.timeoutMs - (Date.now() - info.startedAt)
}
/** 清除单个审批计时器 */
export function clearApprovalTimer(toolCallId: string): void {
const timer = _approvalTimers.get(toolCallId)
if (timer) {
clearTimeout(timer)
const info = _approvalTimers.get(toolCallId)
if (info) {
clearTimeout(info.timer)
_approvalTimers.delete(toolCallId)
}
}
/** 清除全部审批计时器(整流超时收尾/组件卸载时调用) */
export function clearAllApprovalTimers(): void {
for (const timer of _approvalTimers.values()) clearTimeout(timer)
for (const info of _approvalTimers.values()) clearTimeout(info.timer)
_approvalTimers.clear()
}