tony.cheng
2026-03-12 bc2b5cf668bbe6ebbb4f090bc476781d8630c2bb
web-app/src/components/common/OutboundCallWidget.jsx
@@ -5,11 +5,19 @@
const OUTBOUND_JOBS_KEY = 'outbound_call_jobs';
// 活跃状态列表(外呼进行中的状态)
const ACTIVE_STATUSES = ['Scheduling', 'InProgress', 'Calling', 'Ringing', 'Answered', 'Executing'];
// 活跃状态列表
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);
/**
 * 智能外呼通话显示组件
@@ -141,11 +149,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);
@@ -186,7 +198,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) {
@@ -210,12 +222,7 @@
    console.log('从 localStorage 读取的所有任务:', storedJobs);
    
    // 分离成功任务和失败任务
    const successJobs = storedJobs.filter(job => {
      const hasNoErrorCode = !job.errorCode;
      const isActiveStatus = ACTIVE_STATUSES.includes(job.callStatus);
      console.log(`任务 ${job.jobId}: errorCode=${job.errorCode}, callStatus=${job.callStatus}, 无错误码=${hasNoErrorCode}, 活跃状态=${isActiveStatus}`);
      return hasNoErrorCode && isActiveStatus;
    });
    const successJobs = storedJobs.filter(job => !job.errorCode && isActiveStatus(job.callStatus));
    const failedJobs = storedJobs.filter(job => job.errorCode > 0);
    
    console.log('成功任务数量:', successJobs.length, '失败任务数量:', failedJobs.length);
@@ -259,21 +266,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; // 标记为删除
              }
@@ -616,14 +628,14 @@
              {call.errorCode > 0 ? (
                // 失败任务显示
                <span>
                  {call.perClassName || '联系人'}
                  {call.perTypeName || '联系人'}
                  {call.trueName && `(${call.trueName})`}:
                  {call.message}
                </span>
              ) : (
                // 成功任务显示
                // 成功任务显示 - 使用 perTypeName 字段(申请方当事人/被申请方当事人)
                <span>
                  正在与{call.perClassName || '申请方'}({call.trueName || call.personId})电话沟通中...
                  正在与{call.perTypeName || '申请方当事人'}({call.trueName || call.personId})电话沟通中...
                </span>
              )}
            </div>
@@ -658,4 +670,4 @@
  );
};
export default OutboundCallWidget;
export default OutboundCallWidget;