| | |
| | | import React, { createContext, useContext, useState, useEffect, useRef } from 'react'; |
| | | import { message } from 'antd'; |
| | | import ProcessAPIService from '../services/ProcessAPIService'; |
| | | import OutboundBotAPIService from '../services/OutboundBotAPIService'; |
| | | import { getMergedParams } from '../utils/urlParams'; |
| | | import { mockTimelineData } from '../mocks/timeline'; |
| | | import { getFallbackStartTime, parseTimeString } from '../utils/timeFormatter'; |
| | |
| | | |
| | | // localStorage键名 |
| | | const STORAGE_KEY = 'case_data_timeline'; |
| | | const OUTBOUND_JOBS_KEY = 'outbound_call_jobs'; |
| | | |
| | | /** |
| | | * CaseDataProvider组件 |
| | |
| | | const [hasLoaded, setHasLoaded] = useState(false); // 防止重复加载 |
| | | |
| | | /** |
| | | * 从localStorage读取数据 |
| | | */ |
| | | const loadFromStorage = () => { |
| | | try { |
| | | const stored = localStorage.getItem(STORAGE_KEY); |
| | | if (stored) { |
| | | return JSON.parse(stored); |
| | | } |
| | | } catch (err) { |
| | | console.error('Failed to load data from localStorage:', err); |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | /** |
| | | * 保存数据到localStorage |
| | | */ |
| | | const saveToStorage = (data) => { |
| | |
| | | localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); |
| | | } catch (err) { |
| | | console.error('Failed to save data to localStorage:', err); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * 检查是否有活跃的外呼任务 |
| | | * @returns {boolean} 是否有活跃任务 |
| | | */ |
| | | const hasActiveOutboundJobs = () => { |
| | | try { |
| | | const stored = localStorage.getItem(OUTBOUND_JOBS_KEY); |
| | | if (!stored) return false; |
| | | |
| | | const jobs = JSON.parse(stored); |
| | | const activeStatuses = ['Scheduling', 'Executing', 'Paused', 'Drafted']; |
| | | |
| | | // 过滤出活跃状态的任务 |
| | | const activeJobs = jobs.filter(job => activeStatuses.includes(job.callStatus)); |
| | | return activeJobs.length > 0; |
| | | } catch (err) { |
| | | console.error('检查活跃外呼任务失败:', err); |
| | | return false; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * 触发智能外呼 |
| | | * @param {Object} timeline - 案件时间线数据 |
| | | */ |
| | | const triggerOutboundCall = async (timeline) => { |
| | | try { |
| | | // 检查是否已有活跃任务,如有则跳过 |
| | | if (hasActiveOutboundJobs()) { |
| | | console.log('检测到活跃外呼任务,跳过发起新外呼'); |
| | | return; |
| | | } |
| | | |
| | | const mediationId = timeline.id; |
| | | const caseId = timeline.case_id; |
| | | |
| | | if (!mediationId || !caseId) { |
| | | console.warn('缺少必要参数,跳过外呼触发:', { mediationId, caseId }); |
| | | return; |
| | | } |
| | | |
| | | console.log('发起智能外呼,mediationId:', mediationId, ', caseId:', caseId); |
| | | |
| | | // 调用外呼API |
| | | const response = await OutboundBotAPIService.makeCallV2({ |
| | | mediationId: String(mediationId), |
| | | caseId: String(caseId), |
| | | callAuto: 0, |
| | | callPersonId: '' |
| | | }); |
| | | |
| | | // 处理响应 |
| | | if (response?.data && Array.isArray(response.data)) { |
| | | const successJobs = []; |
| | | const failedJobs = []; |
| | | |
| | | // 分类成功和失败的记录 |
| | | response.data.forEach(item => { |
| | | if (item.errorCode === 0 && item.jobId) { |
| | | successJobs.push({ |
| | | jobId: item.jobId, |
| | | callStatus: item.callStatus || 'Scheduling', |
| | | personId: item.personId, |
| | | mediationId: item.mediationId, |
| | | caseId: String(caseId), // 添加 caseId 字段用于轮询 |
| | | startTime: Date.now(), |
| | | pollStartTime: Date.now(), |
| | | retryCount: 0 |
| | | }); |
| | | } else { |
| | | failedJobs.push({ |
| | | personId: item.personId, |
| | | message: item.message || '未知错误' |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | // 存储成功的任务到 localStorage |
| | | if (successJobs.length > 0) { |
| | | localStorage.setItem(OUTBOUND_JOBS_KEY, JSON.stringify(successJobs)); |
| | | console.log('存储外呼任务成功,数量:', successJobs.length); |
| | | } |
| | | |
| | | // 提示失败的任务 |
| | | if (failedJobs.length > 0) { |
| | | const failedMsg = failedJobs |
| | | .map(job => `${job.personId}(${job.message})`) |
| | | .join('、'); |
| | | message.warning(`部分联系人外呼失败:${failedMsg}`); |
| | | console.warn('部分外呼失败:', failedJobs); |
| | | } |
| | | } |
| | | } catch (err) { |
| | | console.error('智能外呼发起失败:', err); |
| | | message.error('智能外呼发起失败,请检查网络后重试'); |
| | | } |
| | | }; |
| | | |
| | |
| | | |
| | | // 保存到localStorage |
| | | saveToStorage(timelineData); |
| | | |
| | | // 触发智能外呼 |
| | | await triggerOutboundCall(timelineData); |
| | | |
| | | |
| | | // 加载任务时间数据 |
| | | await loadTaskTime(timelineData); |