From d31819515e4aac228f26e7cbb92c89e0f520e8ac Mon Sep 17 00:00:00 2001
From: tony.cheng <chengmingwei_1984122@126.com>
Date: Mon, 09 Feb 2026 18:08:01 +0800
Subject: [PATCH] feat: 实现智能外呼自动触发与状态监控功能

---
 web-app/src/components/dashboard/MediationProgress.jsx |   80 +++++++++++++++++++++++++++++-----------
 1 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/web-app/src/components/dashboard/MediationProgress.jsx b/web-app/src/components/dashboard/MediationProgress.jsx
index c645804..d7fd167 100644
--- a/web-app/src/components/dashboard/MediationProgress.jsx
+++ b/web-app/src/components/dashboard/MediationProgress.jsx
@@ -1,36 +1,72 @@
 import React from 'react';
 import { useCaseData } from '../../contexts/CaseDataContext';
+import { mockTimelineData } from '../../mocks/timeline';
+
+// 默认节点数据(从Mock获取)
+const defaultNodes = mockTimelineData.data.nodes || [];
 
 /**
  * AI调解进度组件 - 步骤条
+ * 根据processNodes动态生成流程节点,通过nodeState判断状态
  */
 const MediationProgress = () => {
-  const { caseData } = useCaseData();
+  const { processNodes } = useCaseData();
   
-  // 从 timeline 获取当前节点,默认为第1步(order_no从1开始)
-  const currentStep = (caseData?.current_node?.order_no || 1) - 1; // order_no从1开始,数组索引从0开始
-  const steps = [
-    { label: '意愿调查', key: 0 },
-    { label: '材料核实', key: 1 },
-    { label: '事实认定', key: 2 },
-    { label: '达成协议', key: 3 },
-    { label: '履约回访', key: 4 },
-  ];
+  // 使用processNodes,如果为空则使用默认节点
+  const nodes = (processNodes && processNodes.length > 0) ? processNodes : defaultNodes;
+  
+  console.log('MediationProgress - using nodes:', nodes);
+  
+  // 处理nodes为空的情况(理论上不会进入,因为已有默认值)
+  if (!nodes || nodes.length === 0) {
+    return (
+      <div className="mediation-progress">
+        <h3 className="section-title">
+          <i className="fas fa-road"></i> AI调解进度
+        </h3>
+        <div className="progress-steps">
+          <p style={{ textAlign: 'center', color: '#999', padding: '20px' }}>
+            暂无流程数据
+          </p>
+        </div>
+      </div>
+    );
+  }
 
-  // 计算进度线宽度
-  const progressWidth = `${(currentStep) * 20}%`;
+  // 按order_no排序,处理缺失order_no的情况
+  const sortedNodes = [...nodes].sort((a, b) => {
+    const orderA = a.order_no ?? 999;
+    const orderB = b.order_no ?? 999;
+    return orderA - orderB;
+  });
 
-  const getStepClass = (stepKey) => {
-    if (stepKey < currentStep) return 'step completed';
-    if (stepKey === currentStep) return 'step active';
-    return 'step';
+  // 转换为步骤数据格式
+  const steps = sortedNodes.map((node, index) => ({
+    key: index,
+    label: node.node_name || `步骤${index + 1}`,
+    nodeState: node.nodeState ?? -1  // 缺失时默认为-1(未激活)
+  }));
+
+  // 计算已完成节点数量(nodeState === 2)
+  const completedCount = steps.filter(step => step.nodeState === 2).length;
+  
+  // 计算进度线宽度(根据已完成节点数量)
+  const totalSteps = steps.length;
+  const progressWidth = totalSteps > 0 ? `${(completedCount / totalSteps) * 100}%` : '0%';
+
+  // 根据nodeState判断步骤类名
+  const getStepClass = (nodeState) => {
+    if (nodeState === 2) return 'step completed';  // 已完成
+    if (nodeState === 1) return 'step active';  // 激活/进行中
+    return 'step';  // 默认未激活
   };
 
-  const renderStepIndicator = (stepKey) => {
-    if (stepKey < currentStep) {
-      return <i className="fas fa-check"></i>;
+  // 根据nodeState渲染步骤指示器
+  const renderStepIndicator = (nodeState, stepKey) => {
+    if (nodeState === 2) {
+      return <i className="fas fa-check"></i>;  // 完成显示勾
     }
-    return stepKey + 1;
+    return stepKey + 1;  // 激活/未激活显示数字
   };
 
   return (
@@ -42,8 +78,8 @@
       <div className="progress-steps">
         <div className="progress-line" style={{ width: progressWidth }}></div>
         {steps.map((step) => (
-          <div key={step.key} className={getStepClass(step.key)}>
-            <div className="step-indicator">{renderStepIndicator(step.key)}</div>
+          <div key={step.key} className={getStepClass(step.nodeState)}>
+            <div className="step-indicator">{renderStepIndicator(step.nodeState, step.key)}</div>
             <div className="step-label">{step.label}</div>
           </div>
         ))}

--
Gitblit v1.8.0