| web-app/src/components/common/OutboundCallWidget.jsx | ●●●●● patch | view | raw | blame | history | |
| web-app/src/components/dashboard/TabContainer.jsx | ●●●●● patch | view | raw | blame | history | |
| web-app/src/contexts/CaseDataContext.jsx | ●●●●● patch | view | raw | blame | history | |
| web-app/src/services/MediationAgreementAPIService.js | ●●●●● patch | view | raw | blame | history | |
| web-app/src/services/OutboundBotAPIService.js | ●●●●● patch | view | raw | blame | history | |
| web-app/src/utils/urlParams.js | ●●●●● patch | view | raw | blame | history |
web-app/src/components/common/OutboundCallWidget.jsx
@@ -6,10 +6,18 @@ const OUTBOUND_JOBS_KEY = 'outbound_call_jobs'; // 活跃状态列表 const ACTIVE_STATUSES = ['Scheduling', 'InProgress', 'Calling', 'Ringing', 'Answered']; const ACTIVE_STATUSES = ['Scheduling', 'Executing', 'Paused', 'Drafted', 'InProgress', 'Calling', 'Ringing', 'Answered']; // Scheduling 状态 - 此状态变化不需要调用更新API const SCHEDULING_STATUS = 'Scheduling'; const BACKEND_STATUSES = ['Scheduling', 'Executing', 'Succeeded', 'Paused', 'Failed', 'Cancelled', 'Drafted']; const STATUS_TO_BACKEND = { InProgress: 'Executing', Calling: 'Executing', Ringing: 'Executing', Answered: 'Executing' }; const isActiveStatus = (status) => !status || ACTIVE_STATUSES.includes(status); /** * 智能外呼通话显示组件 @@ -139,11 +147,15 @@ const results = await Promise.all( jobsToUpdate.map(async (job) => { try { const statusToUpdate = job.backendStatus || job.newStatus; if (!statusToUpdate) { return { success: false, job }; } await OutboundBotAPIService.updateCallStatus({ jobId: job.jobId, callStatus: job.newStatus callStatus: statusToUpdate }); console.log(`状态更新成功: ${job.jobId} -> ${job.newStatus}`); console.log(`状态更新成功: ${job.jobId} -> ${statusToUpdate}`); return { success: true, job }; } catch (err) { console.error(`状态更新失败: ${job.jobId}`, err); @@ -184,7 +196,7 @@ const now = Date.now(); return jobs.filter(job => { // 检查是否为活跃状态 if (ACTIVE_STATUSES.includes(job.callStatus)) { if (isActiveStatus(job.callStatus)) { // 检查是否超时(2小时) const elapsed = now - (job.pollStartTime || job.startTime || now); if (elapsed > 2 * 60 * 60 * 1000) { @@ -205,7 +217,7 @@ const storedJobs = loadJobsFromStorage(); // 分离成功任务和失败任务 const successJobs = storedJobs.filter(job => !job.errorCode && ACTIVE_STATUSES.includes(job.callStatus)); const successJobs = storedJobs.filter(job => !job.errorCode && isActiveStatus(job.callStatus)); const failedJobs = storedJobs.filter(job => job.errorCode > 0); if (successJobs.length === 0) { @@ -234,21 +246,26 @@ if (response?.data) { const newStatus = response.data.callStatus; if (!newStatus) { return job; } const backendStatus = STATUS_TO_BACKEND[newStatus] || newStatus; // 如果状态发生变化,更新任务 if (newStatus !== job.callStatus) { console.log(`任务 ${job.jobId} 状态更新: ${job.callStatus} -> ${newStatus}`); // 检查是否需要调用后端更新API(排除Scheduling状态) if (job.callStatus !== SCHEDULING_STATUS) { if (backendStatus !== SCHEDULING_STATUS && BACKEND_STATUSES.includes(backendStatus)) { jobsNeedBackendUpdate.push({ ...job, newStatus newStatus, backendStatus }); } // 如果是终态,可以从轮询中移除 if (!ACTIVE_STATUSES.includes(newStatus)) { if (!isActiveStatus(newStatus)) { console.log(`任务 ${job.jobId} 达到终态: ${newStatus}`); return null; // 标记为删除 } web-app/src/components/dashboard/TabContainer.jsx
@@ -1430,7 +1430,7 @@ if (!caseId) return; setActionLoading(prev => ({ ...prev, regenerate: true })); try { const response = await MediationAgreementAPIService.generateAgreement(caseId); const response = await MediationAgreementAPIService.regenerateAgreement(caseId); if (response?.data?.agreeContent) { setAgreementContent(response.data.agreeContent); message.success('协议重新生成成功!'); web-app/src/contexts/CaseDataContext.jsx
@@ -52,7 +52,16 @@ if (!stored) return false; const jobs = JSON.parse(stored); const activeStatuses = ['Scheduling', 'Executing', 'Paused', 'Drafted']; const activeStatuses = [ 'Scheduling', 'Executing', 'Paused', 'Drafted', 'InProgress', 'Calling', 'Ringing', 'Answered' ]; // 过滤出活跃状态的任务 const activeJobs = jobs.filter(job => activeStatuses.includes(job.callStatus)); @@ -255,6 +264,23 @@ console.log('Loading case data with params:', params); if (!params.caseId) { setError('caseId缺失'); setLoading(false); return; } try { await OutboundBotAPIService.syncStatusByCase({ caseId: params.caseId }); } catch (syncError) { console.error('同步外呼状态失败:', syncError); } try { await OutboundBotAPIService.backfillConversationByCase({ caseId: params.caseId }); } catch (backfillError) { console.error('回补通话记录失败:', backfillError); } // 调用API获取数据 const response = await ProcessAPIService.getCaseProcessInfo( params.caseId, web-app/src/services/MediationAgreementAPIService.js
@@ -68,7 +68,7 @@ * @returns {Promise} 重新生成的协议信息(包含新的agreeId和agreeContent) */ static regenerateAgreement(caseId) { return request.post('/api/v1/medi-agreement/regenerate', { caseId }); return request.post('/api/v1/medi-agreement/regenerate', { caseId }, { timeout: 120000 }); } } web-app/src/services/OutboundBotAPIService.js
@@ -60,6 +60,14 @@ static updateCallStatus(data) { return request.post('/api/v1/outbound-bot/update-status', data); } static syncStatusByCase(data) { return request.post('/api/v1/outbound-bot/sync-status-by-case', data); } static backfillConversationByCase(data) { return request.post('/api/v1/outbound-bot/backfill-conversation-by-case', data); } } export default OutboundBotAPIService; web-app/src/utils/urlParams.js
@@ -9,7 +9,7 @@ */ export const getDefaultParams = () => { return { caseId: '202601281644031088', caseId: '202602261114241000', caseTypeFirst: '24_01-2', caseType: '24_02-9', platform_code: 'AI_0001',