feat:抢单大厅数据排列优化
This commit is contained in:
@@ -21,6 +21,13 @@ type UseRealtimeEventsOptions = {
|
||||
token: string
|
||||
onEvent: (event: RealtimeEvent) => void
|
||||
onConnected?: () => void
|
||||
/**
|
||||
* 服务端告知「补发窗口溢出,历史事件已不连续」。
|
||||
*
|
||||
* 此时不能再依赖逐条快照补丁(会把列表写回旧值),调用方应整体失效对应查询,
|
||||
* 让列表接口重新给出权威数据。
|
||||
*/
|
||||
onResync?: (info: { headEventId: number; reason: string }) => void
|
||||
/** 鉴权失效(401/403)时触发:连接停止重连,调用方应清理会话并跳转登录页。 */
|
||||
onAuthExpired?: () => void
|
||||
}
|
||||
@@ -33,13 +40,16 @@ export function useRealtimeEvents({
|
||||
token,
|
||||
onEvent,
|
||||
onConnected,
|
||||
onResync,
|
||||
onAuthExpired,
|
||||
}: UseRealtimeEventsOptions) {
|
||||
const onEventRef = useRef(onEvent)
|
||||
const onConnectedRef = useRef(onConnected)
|
||||
const onResyncRef = useRef(onResync)
|
||||
const onAuthExpiredRef = useRef(onAuthExpired)
|
||||
onEventRef.current = onEvent
|
||||
onConnectedRef.current = onConnected
|
||||
onResyncRef.current = onResync
|
||||
onAuthExpiredRef.current = onAuthExpired
|
||||
|
||||
useEffect(() => {
|
||||
@@ -79,6 +89,15 @@ export function useRealtimeEvents({
|
||||
}
|
||||
onConnectedRef.current?.()
|
||||
await readSseStream(response.body, (eventName, data) => {
|
||||
// 补发窗口溢出:历史事件不连续,不能逐条复位快照,交给调用方整体重拉。
|
||||
if (eventName === 'resync') {
|
||||
const notice = normalizeResyncNotice(data)
|
||||
if (notice) {
|
||||
lastEventId = Math.max(lastEventId, notice.headEventId)
|
||||
onResyncRef.current?.(notice)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (eventName !== 'realtime') return
|
||||
const event = normalizeRealtimeEvent(data)
|
||||
if (event) {
|
||||
@@ -197,3 +216,16 @@ function normalizeRealtimeEvent(value: string): RealtimeEvent | null {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/** 服务端 resync 通知:补发窗口溢出,客户端应把游标推进到 headEventId 并整体重拉。 */
|
||||
function normalizeResyncNotice(value: string): { headEventId: number; reason: string } | null {
|
||||
try {
|
||||
const parsed = JSON.parse(value) as { headEventId?: unknown; reason?: unknown }
|
||||
return {
|
||||
headEventId: Math.max(0, Number(parsed.headEventId) || 0),
|
||||
reason: String(parsed.reason || ''),
|
||||
}
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user