tony.cheng
2026-03-03 844c875028a3aee6d2ffc910e72681c41fce2caf
feat: 完善案件数据上下文和外呼组件功能
6 files modified
45 ■■■■■ changed files
document/原型/index.html 8 ●●●● patch | view | raw | blame | history
web-app/src/components/common/OutboundCallWidget.jsx 2 ●●● patch | view | raw | blame | history
web-app/src/components/dashboard/MediationProgress.jsx 10 ●●●● patch | view | raw | blame | history
web-app/src/components/dashboard/TopSection.jsx 10 ●●●● patch | view | raw | blame | history
web-app/src/contexts/CaseDataContext.jsx 11 ●●●●● patch | view | raw | blame | history
web-app/src/utils/urlParams.js 4 ●●●● patch | view | raw | blame | history
document/原型/index.html
@@ -1349,19 +1349,19 @@
                <div class="case-info">
                    <div class="info-item">
                        <div class="info-label">事项编号</div>
                        <div class="info-value">LD-2026-0014</div>
                        <div class="info-value">----</div>
                    </div>
                    <div class="info-item">
                        <div class="info-label">纠纷类型</div>
                        <div class="info-value">劳动争议/拖欠、克扣工资</div>
                        <div class="info-value">----</div>
                    </div>
                    <div class="info-item">
                        <div class="info-label">调解开始时间</div>
                        <div class="info-value">2026-01-15 09:30</div>
                        <div class="info-value">----</div>
                    </div>
                    <div class="info-item">
                        <div class="info-label">预计结束时间</div>
                        <div class="info-value">2026-01-15 11:00</div>
                        <div class="info-value">----</div>
                    </div>
                </div>
            </div>
web-app/src/components/common/OutboundCallWidget.jsx
@@ -21,7 +21,7 @@
const OutboundCallWidget = ({ onSwitchTab, onRefreshData }) => {
  const { caseData } = useCaseData();
  const [isVisible, setIsVisible] = useState(false); // 默认隐藏
  const [isMinimized, setIsMinimized] = useState(true);
  const [isMinimized, setIsMinimized] = useState(false); // 默认展开(非最小化)
  const [calls, setCalls] = useState([]);
  const isMountedRef = useRef(true);
  
web-app/src/components/dashboard/MediationProgress.jsx
@@ -33,17 +33,17 @@
    );
  }
  // 按order_no排序,处理缺失order_no的情况
  // 按orderNo排序,兼容 orderNo 和 order_no 两种字段名
  const sortedNodes = [...nodes].sort((a, b) => {
    const orderA = a.order_no ?? 999;
    const orderB = b.order_no ?? 999;
    const orderA = a.orderNo ?? a.order_no ?? 999;
    const orderB = b.orderNo ?? b.order_no ?? 999;
    return orderA - orderB;
  });
  // 转换为步骤数据格式
  // 转换为步骤数据格式,兼容 nodeName 和 node_name 两种字段名
  const steps = sortedNodes.map((node, index) => ({
    key: index,
    label: node.node_name || `步骤${index + 1}`,
    label: node.nodeName || node.node_name || `步骤${index + 1}`,
    nodeState: node.nodeState ?? -1  // 缺失时默认为-1(未激活)
  }));
web-app/src/components/dashboard/TopSection.jsx
@@ -10,11 +10,11 @@
  const timeline = caseData || {};
  
  // 从 timeline 中获取数据,提供默认值
  const caseNumber = timeline.case_ref || 'LD-2026-0014';
  const disputeType = timeline.case_type_first_name || '劳动争议/拖欠、克扣工资';
  const startTime = timeline.mediation?.start_date || '2026-01-15 09:30';
  const endTime = timeline.mediation?.end_date || '2026-01-15 11:00';
  const aiStatus = translateMediationState(timeline.mediation?.state) || 'AI调解中';
  const caseNumber = timeline.case_ref || '---';
  const disputeType = timeline.case_type_first_name || '---';
  const startTime = timeline.mediation?.start_date || '---';
  const endTime = timeline.mediation?.end_date || '---';
  const aiStatus = translateMediationState(timeline.mediation?.state) || '---';
  return (
    <section className="top-section">
web-app/src/contexts/CaseDataContext.jsx
@@ -139,6 +139,17 @@
        if (successJobs.length > 0) {
          localStorage.setItem(OUTBOUND_JOBS_KEY, JSON.stringify(successJobs));
          console.log('存储外呼任务成功,数量:', successJobs.length);
          // 外呼成功后,清除对应的失败记录
          const storedFailedJobs = JSON.parse(localStorage.getItem(`${OUTBOUND_JOBS_KEY}_failed`) || '[]');
          if (storedFailedJobs.length > 0) {
            // 获取成功任务的 personId 列表
            const successPersonIds = successJobs.map(job => job.personId);
            // 过滤掉已成功的 personId 对应的失败记录
            const remainingFailedJobs = storedFailedJobs.filter(job => !successPersonIds.includes(job.personId));
            localStorage.setItem(`${OUTBOUND_JOBS_KEY}_failed`, JSON.stringify(remainingFailedJobs));
            console.log('外呼成功后清除失败记录,清除数量:', storedFailedJobs.length - remainingFailedJobs.length);
          }
        }
        // 存储失败的任务到 localStorage(用于气泡显示)
web-app/src/utils/urlParams.js
@@ -39,11 +39,11 @@
 * @returns {Object} 合并后的参数对象
 */
export const getMergedParams = () => {
  const defaultParams = getDefaultParams();
  // const defaultParams = getDefaultParams();
  const urlParams = parseUrlParams();
  
  return {
    ...defaultParams,
    // ...defaultParams,
    ...urlParams
  };
};