/** 合并聊天窗口的收发事件;每次同步只接受后端读取的云端消息,不上报客户端正文。 */ export function createImChatArchiveTrigger( syncPage: (params: { diagnosis_id: number; scope: 'current'; sync_token?: string }) => Promise<{ sync_token?: string; completed: boolean; errors?: string[] }>, onError: (error: unknown) => void = () => {} ) { const jobs = new Map }>() return (diagnosisId: number): Promise => { if (!Number.isInteger(diagnosisId) || diagnosisId <= 0) return Promise.resolve() const pending = jobs.get(diagnosisId) if (pending) { pending.again = true return pending.promise } const job = { again: false, promise: Promise.resolve() } jobs.set(diagnosisId, job) job.promise = (async () => { try { do { job.again = false let token: string | undefined for (;;) { const result = await syncPage({ diagnosis_id: diagnosisId, scope: 'current', sync_token: token }) if (result.completed) { if (result.errors?.length) throw new Error(result.errors.join(';')) break } if (!result.sync_token) throw new Error('聊天记录同步未返回进度') token = result.sync_token } // 同步期间收到新消息时再追一次,覆盖新消息晚于本轮首页的情况。 } while (job.again) } catch (error) { onError(error) } finally { jobs.delete(diagnosisId) } })() return job.promise } }