系统在首页加载案件数据完成后,SHALL 自动发起 AI 智能外呼,无需用户手动操作。外呼请求应基于案件数据(mediationId、caseId)构建,并确保幂等性(页面刷新时不重复触发)。
CaseDataContext.loadCaseData() 完成并返回 timelineDataOutboundBotAPIService.makeCallV2({ mediationId, caseId, callAuto: 0, callPersonId: null })response.data 中提取所有 errorCode === 0 的记录jobId、callStatus、personId、mediationId 存储到 localStorage(键名:outbound_call_jobs)callStatus 为 Scheduling、Executing、Paused 或 Drafted)CaseDataContext.loadCaseData() 执行makeCallV2 失败(如网络错误、API 返回 500)message.error('发起外呼失败,请稍后重试')console.error('makeCallV2 failed:', err)makeCallV2 响应包含多条记录,其中部分 errorCode === 0(成功),部分 errorCode !== 0(失败)errorCode === 0 的记录到 localStorage系统 SHALL 对活跃外呼任务进行定时轮询,查询通话状态并实时更新右下角气泡组件显示。轮询策略应平衡实时性与服务器压力,采用 10 秒间隔、最大 2 小时轮询时长、失败重试 10 次的机制。
callStatus 为 Scheduling、Executing、Paused 或 Drafted)OutboundCallWidget 组件挂载后启动轮询定时器(间隔 10 秒)OutboundBotAPIService.getCallStatus({ jobId })callStatus,更新组件内部 calls 状态数组callStatus 变为 Succeeded(成功)outbound_call_jobs 中移除该 jobIdcalls 状态数组,移除对应记录isVisible=false)pollStartTime 开始计时)console.warn('轮询超时,jobId: xxx')getCallStatus 失败(如网络抖动、API 返回 500)retryCount 计数器console.warn('查询失败,重试次数: X/10, jobId: xxx')retryCount 已达到 10message.error('获取通话状态失败,请检查网络连接')console.error('重试次数超限,jobId: xxx')系统 SHALL 支持同时展示多个外呼任务的状态(如申请人、被申请人同时外呼),气泡组件采用纵向堆叠布局,每个任务独立显示通话人和状态信息。
makeCallV2 响应返回 2 条成功记录(2 个 jobId)Succeeded(成功)callStatus 为 Succeeded、Failed 或 Cancelled)系统 SHALL 在组件卸载或用户离开页面时正确清理定时器和资源,避免内存泄漏和控制台报错。
OutboundCallWidget 组件已挂载并启动轮询定时器useEffect 的清理函数中调用 clearInterval(intervalId)OutboundCallWidget 组件卸载outbound_call_jobs 数据保持不变getCallStatus 异步请求useRef 记录 isMounted 状态isMounted,如果组件已卸载则不执行状态更新系统 SHALL 将 API 返回的英文通话状态映射为中文,便于用户理解当前外呼进度。
callStatus 为英文值Scheduling → "拨号中"Executing → "通话中"Paused → "已暂停"Drafted → "草稿"Succeeded → "已完成"Failed → "失败"Cancelled → "已取消"startTime 字段(时间戳或 ISO 格式字符串)startTime 的差值(秒)系统 SHALL 在关键操作失败时提供友好的错误提示,并在浏览器控制台输出详细日志,便于开发调试。
makeCallV2 失败(如网络错误、API 返回 500)message.error('发起外呼失败,请稍后重试')console.error('makeCallV2 failed:', err)message.error('获取通话状态失败,请检查网络连接')console.error('重试次数超限,jobId: xxx')console.log('发起外呼,mediationId: X, caseId: Y')console.log('存储 jobId: X, callStatus: Y')console.log('轮询查询 jobId: X')console.log('检测到终态,移除 jobId: X')