const RUNNING_STATE = 0 const SUCCESS_STATE = 1 const FAILED_STATE = -1 function toNumber(value) { if (value === '' || value === null || value === undefined) return undefined const numeric = Number(value) return Number.isNaN(numeric) ? undefined : numeric } function pickReportId(source) { if (source === null || source === undefined) return undefined if (typeof source === 'number') return source if (typeof source === 'string') { const numeric = toNumber(source) return numeric === undefined ? undefined : numeric } if (typeof source !== 'object') return undefined const direct = toNumber(source.reportId ?? source.id) if (direct !== undefined) return direct for (const key of ['data', 'dto', 'info']) { const nested = pickReportId(source[key]) if (nested !== undefined) return nested } return undefined } function extractReportId(payload) { return pickReportId(payload) } function normalizeGenerationStatus(payload = {}) { const source = payload && typeof payload === 'object' ? payload : {} const state = toNumber(source.state) return { reportId: extractReportId(source) ?? '', state: state === undefined ? RUNNING_STATE : state, status: source.status || '', errorMessage: source.errorMessage || '' } } function applyGenerationStatus(payload = {}) { const generation = normalizeGenerationStatus(payload) if (generation.state === FAILED_STATE) { return { ...generation, title: '报告生成失败', subtitle: '', description: generation.errorMessage || '失败原因:网络延迟', errorMessage: generation.errorMessage || '网络延迟', polling: false, actionText: '重新生成', imageKey: 'fail' } } if (generation.state === SUCCESS_STATE) { return { ...generation, title: '报告生成成功', subtitle: '', description: '报告已生成完成,你可以去我的PREILL报告查阅报告结果。', errorMessage: '', polling: false, actionText: '返回', imageKey: 'success' } } return { ...generation, title: '报告正在生成中~', subtitle: '预计所需时间1小时左右', description: '我们会在报告生成完成后提示你,你可以去我的PREILL报告查阅报告结果。', errorMessage: '', polling: true, actionText: '返回', imageKey: 'success' } } function replaceFirstPage(currentList, nextList) { void currentList return Array.isArray(nextList) ? nextList.slice() : [] } function shouldResumePolling(reportId, generation = {}) { return Boolean(reportId && normalizeGenerationStatus(generation).state === RUNNING_STATE) } function reconcileStatusQueryError(currentGeneration = {}) { return applyGenerationStatus(normalizeGenerationStatus(currentGeneration)) } function createStatusRequestState() { return { isPageVisible: false, statusVisibilityToken: 0, statusRequestSeq: 0, statusActiveRequestId: 0, statusRequestInFlight: false } } function setStatusPageVisible(state, visible) { if (!state || state.isPageVisible === visible) return state ? state.statusVisibilityToken : 0 state.isPageVisible = visible if (!visible) { state.statusVisibilityToken += 1 state.statusActiveRequestId = 0 state.statusRequestInFlight = false } return state.statusVisibilityToken } function beginStatusRequest(state) { if (!state || !state.isPageVisible || state.statusRequestInFlight) return null state.statusRequestSeq += 1 state.statusActiveRequestId = state.statusRequestSeq state.statusRequestInFlight = true return { requestId: state.statusActiveRequestId, visibilityToken: state.statusVisibilityToken } } function shouldApplyStatusResponse(state, meta) { return Boolean( state && meta && state.isPageVisible && state.statusRequestInFlight && state.statusActiveRequestId === meta.requestId && state.statusVisibilityToken === meta.visibilityToken ) } function finishStatusRequest(state, meta) { if (!state || !meta) return if (state.statusActiveRequestId === meta.requestId) { state.statusActiveRequestId = 0 state.statusRequestInFlight = false } } function createListRefreshState() { return { refreshGeneration: 0, inFlightPageRequests: {} } } function beginListRefresh(state) { if (!state) return 0 state.refreshGeneration += 1 return state.refreshGeneration } function createListRequestMeta(generation, page) { return { generation, page } } function shouldApplyListResponse(currentGeneration, meta) { return Boolean(meta && currentGeneration === meta.generation) } function beginListPageRequest(state, generation, page) { if (!state) return null const key = `${generation}:${page}` if (state.inFlightPageRequests[key]) return null const meta = { generation, page, key } state.inFlightPageRequests[key] = true return meta } function finishListPageRequest(state, meta) { if (!state || !meta || !meta.key) return delete state.inFlightPageRequests[meta.key] } module.exports = { RUNNING_STATE, SUCCESS_STATE, FAILED_STATE, extractReportId, normalizeGenerationStatus, applyGenerationStatus, replaceFirstPage, shouldResumePolling, reconcileStatusQueryError, createStatusRequestState, setStatusPageVisible, beginStatusRequest, shouldApplyStatusResponse, finishStatusRequest, createListRefreshState, beginListRefresh, createListRequestMeta, shouldApplyListResponse, beginListPageRequest, finishListPageRequest }