From 9161ffccb37c3e707f746674b2bace107bb1014f Mon Sep 17 00:00:00 2001
From: tony.cheng <chengmingwei_1984122@126.com>
Date: Thu, 12 Feb 2026 18:06:49 +0800
Subject: [PATCH] feat: 实现通话状态变化时更新API并刷新页面

---
 web-app/src/components/dashboard/TabContainer.jsx | 1266 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 1,123 insertions(+), 143 deletions(-)

diff --git a/web-app/src/components/dashboard/TabContainer.jsx b/web-app/src/components/dashboard/TabContainer.jsx
index 2b42c5f..cd5b0dc 100644
--- a/web-app/src/components/dashboard/TabContainer.jsx
+++ b/web-app/src/components/dashboard/TabContainer.jsx
@@ -1,21 +1,41 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
 import { useCaseData } from '../../contexts/CaseDataContext';
 import { formatDuration, formatSuccessRate, formatRoundCount } from '../../utils/stateTranslator';
 import ProcessAPIService from '../../services/ProcessAPIService';
-import { message, Spin } from 'antd';
+import EvidenceAPIService from '../../services/EvidenceAPIService';
+import MediationAgreementAPIService from '../../services/MediationAgreementAPIService';
+import { getMergedParams } from '../../utils/urlParams';
+import { message, Spin, Tag, Modal, Button, Input, Image } from 'antd';
+
+const { TextArea } = Input;
 
 /**
  * 选项卡容器组件 - 4个选项卡
+ * 通过 forwardRef 暴露 switchTab 方法供父组件调用
  */
-const TabContainer = () => {
+const TabContainer = forwardRef((props, ref) => {
   const [activeTab, setActiveTab] = useState('mediation-data-board');
+  // 证据材料汇总Tab的审核状态badge
+  const [evidenceBadge, setEvidenceBadge] = useState(null);
+
+  // 暴露 switchTab 方法给父组件
+  useImperativeHandle(ref, () => ({
+    switchTab: (tabKey) => {
+      setActiveTab(tabKey);
+    }
+  }));
 
   const tabs = [
     { key: 'mediation-data-board', label: '调解分析', icon: 'fa-chart-line' },
     { key: 'mediation-board', label: 'AI调解实时看板', icon: 'fa-tv' },
-    { key: 'evidence-board', label: '证据材料汇总', icon: 'fa-file-alt', badge: '待审核' },
+    { key: 'evidence-board', label: '证据材料汇总', icon: 'fa-file-alt', badge: evidenceBadge },
     { key: 'agreement-section', label: '调解协议', icon: 'fa-file-contract', badge: '待确认' },
   ];
+
+  // 更新证据材料汇总Tab的badge状态
+  const handleEvidenceStatusChange = (status) => {
+    setEvidenceBadge(status);
+  };
 
   return (
     <div className="tab-container">
@@ -51,7 +71,7 @@
         {/* 证据材料汇总 */}
         <div className={`tab-pane ${activeTab === 'evidence-board' ? 'active' : ''}`}>
           <div className="tab-content-area">
-            <EvidenceBoard />
+            <EvidenceBoard onStatusChange={handleEvidenceStatusChange} />
           </div>
         </div>
 
@@ -64,7 +84,7 @@
       </div>
     </div>
   );
-};
+});
 
 /**
  * 调解数据看板
@@ -426,20 +446,316 @@
 /**
  * 证据材料汇总
  */
-const EvidenceBoard = () => {
-  const applicantEvidence = [
-    { name: '劳动合同', desc: '2023年8月1日-2026年1月31日,约定月工资¥14,000', time: '2026-01-15 09:35', status: 'verified' },
-    { name: '2026年1-3月工资条', desc: '显示工资发放记录,1月后无发放记录', time: '2026-01-15 09:36', status: 'verified' },
-    { name: '2026年第一季度考勤记录', desc: '显示全勤,无请假缺勤记录', time: '2026-01-15 09:37', status: 'verified' },
-    { name: '绩效考评表', desc: '第一季度绩效评分85分,达到奖金发放标准', time: '2026-01-15 09:38', status: 'verified' },
-    { name: '解除劳动合同通知书', desc: '公司2026年1月15日单方面解除合同', time: '2026-01-15 09:45', status: 'pending' },
-  ];
+const EvidenceBoard = ({ onStatusChange }) => {
+  const [loading, setLoading] = useState(false);
+  const [error, setError] = useState(null);
+  // 审核弹窗状态
+  const [auditModalVisible, setAuditModalVisible] = useState(false);
+  const [currentAuditItem, setCurrentAuditItem] = useState(null);
+  const [auditRemark, setAuditRemark] = useState('');
+  const [auditLoading, setAuditLoading] = useState(false);
+  const [returnModalVisible, setReturnModalVisible] = useState(false);
+  const [applicantMaterials, setApplicantMaterials] = useState([]);
+  const [respondentMaterials, setRespondentMaterials] = useState([]);
+  // 弹窗数据状态
+  const [modalDataLoading, setModalDataLoading] = useState(false);
+  const [personInfo, setPersonInfo] = useState(null);
+  const [evidenceImages, setEvidenceImages] = useState([]);
+  const [platformUrl, setPlatformUrl] = useState('');
 
-  const respondentEvidence = [
-    { name: '2026年1-3月考勤异常记录', desc: '显示李晓明1月有2天事假,应扣款¥1,333', time: '2026-01-15 09:50', status: 'pending' },
-    { name: '第一季度销售业绩报表', desc: '显示李晓明未完成销售KPI指标(完成率87%)', time: '2026-01-15 09:52', status: 'pending' },
-    { name: '员工离职申请表', desc: '李晓明2026年1月10日提交的辞职申请', time: '2026-01-15 09:55', status: 'pending' },
-  ];
+  // 计算整体审核状态(综合申请人和被申请人所有材料)
+  const calculateOverallTabStatus = (applicantList, respondentList) => {
+    const allMaterials = [...applicantList, ...respondentList];
+    if (!allMaterials || allMaterials.length === 0) return null;
+    
+    // 存在驳回状态 -> 显示"驳回"
+    const hasRejected = allMaterials.some(m => m.audit_state === -2);
+    if (hasRejected) return '驳回';
+    
+    // 存在待审核状态(0或-2) -> 显示"待审核"
+    const hasPending = allMaterials.some(m => m.audit_state === 0 || m.audit_state === -2);
+    if (hasPending) return '待审核';
+    
+    // 所有材料都已审核 -> 显示"已审核"
+    return '已审核';
+  };
+
+  // 加载数据
+  const loadData = async () => {
+    // 使用getMergedParams获取参数(URL参数优先,默认值兜底)
+    const params = getMergedParams();
+    const caseId = params.caseId;
+    const caseType = params.caseTypeFirst;
+    const platformCode = params.platform_code;
+    
+    console.log('EvidenceBoard loadData params:', { caseId, caseType, platformCode });
+    
+    setLoading(true);
+    setError(null);
+    
+    try {
+      // 调用API获取数据
+      const response = await EvidenceAPIService.getEvidenceList({
+        case_id: caseId,
+        case_type: caseType,
+        platform_code: platformCode
+      });
+      
+      console.log('EvidenceBoard API response:', response);
+      
+      const responseData = response.data || [];
+      
+      // 分离申请人和被申请人材料
+      const applicantData = responseData.find(item => item.per_type === '15_020008-1');
+      const respondentData = responseData.find(item => item.per_type === '15_020008-2');
+      
+      const applicantList = applicantData?.file_list?.slice(0, applicantData.file_count) || [];
+      const respondentList = respondentData?.file_list?.slice(0, respondentData.file_count) || [];
+      
+      setApplicantMaterials(applicantList);
+      setRespondentMaterials(respondentList);
+      
+      // 计算并通知Tab标题的整体审核状态
+      const overallStatus = calculateOverallTabStatus(applicantList, respondentList);
+      if (onStatusChange) {
+        onStatusChange(overallStatus);
+      }
+      
+    } catch (err) {
+      console.error('加载证据材料失败:', err);
+      setError('数据加载失败,请稍后重试');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  // 组件挂载时加载数据
+  useEffect(() => {
+    loadData();
+  }, []); // eslint-disable-line react-hooks/exhaustive-deps
+
+  // 计算区域内整体审核状态(用于卡片标题旁的Tag显示)
+  const calculateOverallStatus = (materials) => {
+    if (!materials || materials.length === 0) return { text: '无数据', color: 'default' };
+    const hasRejected = materials.some(m => m.audit_state === -2);
+    if (hasRejected) return { text: '驳回', color: 'red' };
+    const hasPending = materials.some(m => m.audit_state === 0 || m.audit_state === -2);
+    if (hasPending) return { text: '待审核', color: 'orange' };
+    return { text: '已审核', color: 'green' };
+  };
+
+  const applicantStatus = calculateOverallStatus(applicantMaterials);
+  const respondentStatus = calculateOverallStatus(respondentMaterials);
+
+  // Loading状态
+  if (loading) {
+    return (
+      <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 300 }}>
+        <Spin size="large" tip="加载证据材料中..." />
+      </div>
+    );
+  }
+
+  // 错误状态
+  if (error) {
+    return (
+      <div style={{ textAlign: 'center', padding: 40, color: '#ff4d4f' }}>
+        <div style={{ fontSize: '1.2rem', marginBottom: 10 }}>
+          <i className="fas fa-exclamation-circle"></i> 数据加载失败
+        </div>
+        <div>{error}</div>
+        <button onClick={loadData} style={{
+          marginTop: 15, padding: '8px 16px', backgroundColor: '#1890ff',
+          color: 'white', border: 'none', borderRadius: 4, cursor: 'pointer'
+        }}>重新加载</button>
+      </div>
+    );
+  }
+
+  // 获取材料审核状态样式
+  const getAuditStatusStyle = (auditState) => {
+    if (auditState === 1) {
+      // 已审核 - 绿色边框
+      return {
+        color: '#52c41a',
+        background: '#f6ffed',
+        border: '1px solid #b7eb8f',
+        borderRadius: 4,
+        padding: '2px 10px',
+        fontSize: '0.8rem',
+        fontWeight: 500,
+      };
+    }
+    // 待审核 - 橙色边框
+    return {
+      color: '#fa8c16',
+      background: '#fff7e6',
+      border: '1px solid #ffd591',
+      borderRadius: 4,
+      padding: '2px 10px',
+      fontSize: '0.8rem',
+      fontWeight: 500,
+    };
+  };
+
+  // 打开审核弹窗
+  const handleOpenAuditModal = async (item, type) => {
+    // 获取参数
+    const params = getMergedParams();
+    const caseId = params.caseId;
+    
+    // 设置当前审核项
+    const auditItem = { 
+      ...item, 
+      personType: type,
+      per_type: type === 'applicant' ? '15_020008-1' : '15_020008-2'
+    };
+    setCurrentAuditItem(auditItem);
+    setAuditRemark('');
+    setAuditModalVisible(true);
+    
+    // 获取platform_url
+    try {
+      const caseDataTimeline = JSON.parse(localStorage.getItem('case_data_timeline') || '{}');
+      const pUrl = caseDataTimeline?.process_config?.platform_url || '';
+      setPlatformUrl(pUrl);
+    } catch (e) {
+      console.warn('获取platform_url失败:', e);
+    }
+    
+    // 调用API获取弹窗数据
+    setModalDataLoading(true);
+    setPersonInfo(null);
+    setEvidenceImages([]);
+    
+    try {
+      // 并行调用两个API
+      const [personInfoRes, evidenceListRes] = await Promise.all([
+        EvidenceAPIService.getPersonInfo({
+          case_id: caseId,
+          evidence_type: item.evidence_type,
+          per_type: auditItem.per_type
+        }),
+        EvidenceAPIService.getEvidenceListByPerson({
+          case_id: caseId,
+          evidence_type: item.evidence_type,
+          per_type: auditItem.per_type,
+          person_id: item.person_id
+        })
+      ]);
+      
+      console.log('getPersonInfo response:', personInfoRes);
+      console.log('getEvidenceListByPerson response:', evidenceListRes);
+      
+      // 设置当事人信息
+      if (personInfoRes?.data) {
+        setPersonInfo(personInfoRes.data);
+      }
+      
+      // 设置图片列表
+      if (evidenceListRes?.data && Array.isArray(evidenceListRes.data)) {
+        setEvidenceImages(evidenceListRes.data);
+      }
+    } catch (err) {
+      console.error('加载弹窗数据失败:', err);
+      message.error('加载材料详情失败');
+    } finally {
+      setModalDataLoading(false);
+    }
+  };
+
+  // 关闭审核弹窗
+  const handleCloseAuditModal = () => {
+    setAuditModalVisible(false);
+    setCurrentAuditItem(null);
+    setAuditRemark('');
+    setPersonInfo(null);
+    setEvidenceImages([]);
+  };
+
+  // 审核通过
+  const handleAuditPass = async () => {
+    if (!currentAuditItem) return;
+    
+    const params = getMergedParams();
+    const caseId = params.caseId;
+    
+    setAuditLoading(true);
+    try {
+      // 获取文件ID列表
+      const fileIdList = evidenceImages.map(img => img.file_id || img.id).filter(Boolean);
+      
+      await EvidenceAPIService.auditEvidence({
+        case_id: caseId,
+        evidence_type: currentAuditItem.evidence_type,
+        person_id: currentAuditItem.person_id,
+        file_id_list: fileIdList,
+        audit_user: '当前用户', // TODO: 从登录信息获取
+        audit_state: 1,
+        audit_remark: ''
+      });
+      
+      message.success('审核通过!');
+      handleCloseAuditModal();
+      // 重新加载数据
+      loadData();
+    } catch (err) {
+      console.error('审核失败:', err);
+      message.error('审核失败,请重试');
+    } finally {
+      setAuditLoading(false);
+    }
+  };
+
+  // 退回补充
+  const handleAuditReturn = async () => {
+    if (!currentAuditItem) return;
+    if (!auditRemark.trim()) {
+      message.warning('请填写退回意见');
+      return;
+    }
+    
+    const params = getMergedParams();
+    const caseId = params.caseId;
+    
+    setAuditLoading(true);
+    try {
+      // 获取文件ID列表
+      const fileIdList = evidenceImages.map(img => img.file_id || img.id).filter(Boolean);
+      
+      await EvidenceAPIService.auditEvidence({
+        case_id: caseId,
+        evidence_type: currentAuditItem.evidence_type,
+        person_id: currentAuditItem.person_id,
+        file_id_list: fileIdList,
+        audit_user: '当前用户', // TODO: 从登录信息获取
+        audit_state: 2,
+        audit_remark: auditRemark.trim()
+      });
+      
+      message.success('材料已退回,等待补充提交');
+      setReturnModalVisible(false);
+      handleCloseAuditModal();
+      loadData();
+    } catch (err) {
+      console.error('退回失败:', err);
+      message.error('退回失败,请重试');
+    } finally {
+      setAuditLoading(false);
+    }
+  };
+
+  // 打开退回弹窗
+  const handleOpenReturnModal = () => {
+    setAuditRemark('');
+    setReturnModalVisible(true);
+  };
+
+  // 关闭退回弹窗
+  const handleCloseReturnModal = () => {
+    setReturnModalVisible(false);
+    setAuditRemark('');
+  };
 
   const renderEvidenceItem = (item, type) => (
     <div key={item.name} className="evidence-item" style={{
@@ -451,27 +767,52 @@
       justifyContent: 'space-between',
       alignItems: 'flex-start',
       marginBottom: 10,
+      position: 'relative',
     }}>
-      <div style={{ flex: 1 }}>
+      <div style={{ flex: 1, paddingRight: 70 }}>
         <div style={{ fontWeight: 600, fontSize: '0.9rem', marginBottom: 4, color: 'var(--dark-color)' }}>{item.name}</div>
-        <div style={{ fontSize: '0.8rem', color: 'var(--gray-color)', lineHeight: 1.4 }}>{item.desc}</div>
+        <div style={{ fontSize: '0.8rem', color: 'var(--gray-color)', lineHeight: 1.4 }}>{item.result}</div>
         <div style={{ fontSize: '0.75rem', color: 'var(--gray-color)', marginTop: 4, display: 'flex', alignItems: 'center', gap: 5 }}>
           <i className="far fa-clock"></i>
-          <span>上传时间:{item.time}</span>
+          <span>上传时间:{item.update_time || item.create_time}</span>
         </div>
+        {/* 待审核时显示审核按钮 */}
+        {item.audit_state !== 1 && (
+          <button
+            onClick={() => handleOpenAuditModal(item, type)}
+            style={{
+              marginTop: 8,
+              padding: '4px 12px',
+              fontSize: '0.75rem',
+              background: '#1A6FB8',
+              color: 'white',
+              border: 'none',
+              borderRadius: 4,
+              cursor: 'pointer',
+              fontWeight: 600,
+              transition: 'all 0.2s ease',
+            }}
+            onMouseOver={(e) => {
+              e.target.style.background = '#0d4a8a';
+              e.target.style.transform = 'translateY(-1px)';
+            }}
+            onMouseOut={(e) => {
+              e.target.style.background = '#1A6FB8';
+              e.target.style.transform = 'translateY(0)';
+            }}
+          >
+            审核
+          </button>
+        )}
       </div>
-      <div style={{ marginLeft: 10 }}>
-        <span style={{
-          fontSize: '0.75rem',
-          padding: '3px 8px',
-          borderRadius: 12,
-          fontWeight: 600,
-          background: item.status === 'verified' ? '#d4edda' : '#fff3cd',
-          color: item.status === 'verified' ? '#155724' : '#856404',
-          border: `1px solid ${item.status === 'verified' ? '#c3e6cb' : '#ffeaa7'}`,
-        }}>
-          {item.status === 'verified' ? '已审核' : '待审核'}
-        </span>
+      {/* 右上角审核状态标签 */}
+      <div style={{
+        position: 'absolute',
+        top: 12,
+        right: 12,
+        ...getAuditStatusStyle(item.audit_state)
+      }}>
+        {item.audit_state === 1 ? '已审核' : '待审核'}
       </div>
     </div>
   );
@@ -491,10 +832,15 @@
             <i className="fas fa-user-tie" style={{ color: 'var(--primary-color)', marginRight: 8 }}></i>
             申请人材料
           </div>
-          <div style={{ fontSize: '0.85rem', color: 'var(--gray-color)', marginLeft: 'auto' }}>{applicantEvidence.length}份材料</div>
+          <Tag color={applicantStatus.color}>{applicantStatus.text}</Tag>
+          <div style={{ fontSize: '0.85rem', color: 'var(--gray-color)', marginLeft: 'auto' }}>{applicantMaterials.length}份材料</div>
         </div>
-        <div>
-          {applicantEvidence.map((item) => renderEvidenceItem(item, 'applicant'))}
+        <div style={{ maxHeight: 400, overflowY: 'auto' }}>
+          {applicantMaterials.length > 0 ? (
+            applicantMaterials.map((item) => renderEvidenceItem(item, 'applicant'))
+          ) : (
+            <div style={{ textAlign: 'center', padding: 40, color: 'var(--gray-color)' }}>暂无材料</div>
+          )}
         </div>
       </div>
 
@@ -511,12 +857,395 @@
             <i className="fas fa-building" style={{ color: '#e9c46a', marginRight: 8 }}></i>
             被申请人材料
           </div>
-          <div style={{ fontSize: '0.85rem', color: 'var(--gray-color)', marginLeft: 'auto' }}>{respondentEvidence.length}份材料</div>
+          <Tag color={respondentStatus.color}>{respondentStatus.text}</Tag>
+          <div style={{ fontSize: '0.85rem', color: 'var(--gray-color)', marginLeft: 'auto' }}>{respondentMaterials.length}份材料</div>
         </div>
-        <div>
-          {respondentEvidence.map((item) => renderEvidenceItem(item, 'respondent'))}
+        <div style={{ maxHeight: 400, overflowY: 'auto' }}>
+          {respondentMaterials.length > 0 ? (
+            respondentMaterials.map((item) => renderEvidenceItem(item, 'respondent'))
+          ) : (
+            <div style={{ textAlign: 'center', padding: 40, color: 'var(--gray-color)' }}>暂无材料</div>
+          )}
         </div>
       </div>
+
+      {/* 证据材料审查弹窗 */}
+      <Modal
+        title={null}
+        visible={auditModalVisible}
+        onCancel={handleCloseAuditModal}
+        footer={null}
+        width={900}
+        centered
+        destroyOnClose
+        bodyStyle={{ padding: 0 }}
+        className="doc-audit-modal"
+      >
+        {currentAuditItem && (
+          <div style={{ background: '#f5f7fa' }}>
+            {/* 头部 - 蓝色渐变 */}
+            <div style={{
+              background: 'linear-gradient(135deg, #1A6FB8 0%, #0d4a8a 100%)',
+              color: 'white',
+              padding: '20px 30px',
+            }}>
+              <div style={{ fontSize: 20, fontWeight: 600, marginBottom: 8 }}>证据材料审查</div>
+              <div style={{ fontSize: 14, opacity: 0.9 }}>
+                {currentAuditItem.personType === 'applicant' ? '申请人' : '被申请人'}提交的证据材料
+              </div>
+            </div>
+
+            {/* 主体内容 */}
+            <div style={{ padding: '20px 30px', background: 'white', margin: 0 }}>
+              {/* 审核说明 tip-box */}
+              <div style={{
+                background: '#f0f8ff',
+                borderRadius: 8,
+                padding: 16,
+                marginBottom: 24,
+                border: '1px solid #d9eafb',
+              }}>
+                <div style={{ color: '#1A6FB8', marginBottom: 8, fontSize: 15, fontWeight: 600 }}>审核说明</div>
+                <div style={{ color: '#555', fontSize: 14 }}>
+                  请仔细核对申请人提交的材料,确保材料真实、完整、有效。如有疑问或需要补充材料,请使用"退回补充"功能。
+                </div>
+              </div>
+
+              {/* 材料基本信息 */}
+              <div style={{ marginBottom: 24 }}>
+                <div style={{
+                  color: '#1A6FB8',
+                  fontSize: 16,
+                  fontWeight: 600,
+                  marginBottom: 16,
+                  display: 'flex',
+                  alignItems: 'center',
+                }}>
+                  <span style={{
+                    display: 'inline-block',
+                    width: 4,
+                    height: 16,
+                    background: '#1A6FB8',
+                    marginRight: 10,
+                    borderRadius: 2,
+                  }}></span>
+                  材料基本信息
+                </div>
+                {modalDataLoading ? (
+                  <div style={{ textAlign: 'center', padding: 20 }}>
+                    <Spin tip="加载中..." />
+                  </div>
+                ) : (
+                  <div style={{
+                    display: 'grid',
+                    gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
+                    gap: 16,
+                  }}>
+                    <div style={{ display: 'flex', marginBottom: 12 }}>
+                      <span style={{ fontWeight: 500, color: '#666', minWidth: 80 }}>提交人:</span>
+                      <span style={{ color: '#222', fontWeight: 500 }}>
+                        {personInfo 
+                          ? `${personInfo.per_class_name || (currentAuditItem.personType === 'applicant' ? '申请人' : '被申请人')}-${personInfo.true_name || ''}`
+                          : (currentAuditItem.personType === 'applicant' ? '申请方' : '被申请方')}
+                      </span>
+                    </div>
+                    <div style={{ display: 'flex', marginBottom: 12 }}>
+                      <span style={{ fontWeight: 500, color: '#666', minWidth: 80 }}>材料类型:</span>
+                      <span style={{ color: '#222', fontWeight: 500 }}>
+                        {currentAuditItem.evidence_type_name || currentAuditItem.name || '证据材料'}
+                      </span>
+                    </div>
+                    <div style={{ display: 'flex', marginBottom: 12 }}>
+                      <span style={{ fontWeight: 500, color: '#666', minWidth: 80 }}>材料数量:</span>
+                      <span style={{ color: '#222', fontWeight: 500 }}>
+                        {personInfo?.total_count ? `${personInfo.total_count}份` : `${evidenceImages.length || 1}份`}
+                      </span>
+                    </div>
+                    <div style={{ display: 'flex', marginBottom: 12 }}>
+                      <span style={{ fontWeight: 500, color: '#666', minWidth: 80 }}>提交时间:</span>
+                      <span style={{ color: '#222', fontWeight: 500 }}>
+                        {personInfo?.submit_time || currentAuditItem.update_time || currentAuditItem.create_time}
+                      </span>
+                    </div>
+                  </div>
+                )}
+              </div>
+
+              {/* 材料说明 */}
+              <div style={{ marginBottom: 24 }}>
+                <div style={{
+                  color: '#1A6FB8',
+                  fontSize: 16,
+                  fontWeight: 600,
+                  marginBottom: 16,
+                  display: 'flex',
+                  alignItems: 'center',
+                }}>
+                  <span style={{
+                    display: 'inline-block',
+                    width: 4,
+                    height: 16,
+                    background: '#1A6FB8',
+                    marginRight: 10,
+                    borderRadius: 2,
+                  }}></span>
+                  材料说明
+                </div>
+                <div style={{
+                  border: '1px solid #e8e8e8',
+                  borderRadius: 6,
+                  padding: 16,
+                  background: '#fafafa',
+                  minHeight: 100,
+                  fontSize: 14,
+                  lineHeight: 1.7,
+                }}>
+                  <p style={{ marginBottom: 8 }}>
+                    <strong>{currentAuditItem.name}</strong>
+                  </p>
+                  <p style={{ margin: 0, color: '#555' }}>
+                    {currentAuditItem.result || '暂无详细说明'}
+                  </p>
+                </div>
+              </div>
+
+              {/* 材料清单 */}
+              <div style={{ marginBottom: 24 }}>
+                <div style={{
+                  color: '#1A6FB8',
+                  fontSize: 16,
+                  fontWeight: 600,
+                  marginBottom: 16,
+                  display: 'flex',
+                  alignItems: 'center',
+                }}>
+                  <span style={{
+                    display: 'inline-block',
+                    width: 4,
+                    height: 16,
+                    background: '#1A6FB8',
+                    marginRight: 10,
+                    borderRadius: 2,
+                  }}></span>
+                  材料清单
+                </div>
+                <table style={{
+                  width: '100%',
+                  borderCollapse: 'collapse',
+                  borderRadius: 6,
+                  overflow: 'hidden',
+                  boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.03)',
+                  border: '1px solid #f0f0f0',
+                }}>
+                  <thead>
+                    <tr>
+                      <th style={{
+                        background: '#fafafa',
+                        color: '#333',
+                        fontWeight: 600,
+                        textAlign: 'left',
+                        padding: 16,
+                        borderBottom: '1px solid #f0f0f0',
+                        fontSize: 14,
+                        width: '40%',
+                      }}>材料信息</th>
+                      <th style={{
+                        background: '#fafafa',
+                        color: '#333',
+                        fontWeight: 600,
+                        textAlign: 'left',
+                        padding: 16,
+                        borderBottom: '1px solid #f0f0f0',
+                        fontSize: 14,
+                        width: '60%',
+                      }}>材料预览</th>
+                    </tr>
+                  </thead>
+                  <tbody>
+                    <tr>
+                      <td style={{ padding: 16, borderBottom: '1px solid #f5f5f5', verticalAlign: 'top', fontSize: 14 }}>
+                        <div style={{ fontWeight: 600, color: '#333', marginBottom: 6 }}>{currentAuditItem.name}</div>
+                        <div style={{ fontSize: 13, color: '#666', marginBottom: 4 }}>
+                          材料类型:{currentAuditItem.evidence_type_name || '证据材料'}
+                        </div>
+                        <div style={{ fontSize: 13, color: '#666', marginBottom: 4 }}>
+                          文件格式:{personInfo?.suffix || 'PDF/图片'}
+                        </div>
+                        <div style={{ fontSize: 13, color: '#666', marginBottom: 4 }}>
+                          上传时间:{personInfo?.submit_time || currentAuditItem.update_time || currentAuditItem.create_time}
+                        </div>
+                        {personInfo?.total_file_size && (
+                          <div style={{ fontSize: 13, color: '#666', marginBottom: 4 }}>
+                            文件大小:{personInfo.total_file_size}MB
+                          </div>
+                        )}
+                      </td>
+                      <td style={{ padding: 16, borderBottom: '1px solid #f5f5f5', verticalAlign: 'top', fontSize: 14 }}>
+                        {modalDataLoading ? (
+                          <div style={{ textAlign: 'center', padding: 20 }}>
+                            <Spin size="small" />
+                          </div>
+                        ) : evidenceImages.length > 0 ? (
+                          <>
+                            <Image.PreviewGroup>
+                              <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
+                                {evidenceImages.map((img, index) => {
+                                  const imgUrl = img.show_url 
+                                    ? (platformUrl ? `${platformUrl}/${img.show_url}` : img.show_url)
+                                    : '';
+                                  return (
+                                    <div 
+                                      key={img.file_id || img.id || index}
+                                      style={{
+                                        width: 100,
+                                        height: 80,
+                                        borderRadius: 4,
+                                        overflow: 'hidden',
+                                        border: '1px solid #e8e8e8',
+                                        cursor: 'pointer',
+                                        transition: 'all 0.2s',
+                                      }}
+                                    >
+                                      <Image
+                                        src={imgUrl}
+                                        alt={img.file_name || `材料${index + 1}`}
+                                        style={{ width: '100%', height: '100%', objectFit: 'cover' }}
+                                        fallback="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjgwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iODAiIGZpbGw9IiNmNWY1ZjUiLz48dGV4dCB4PSI1MCIgeT0iNDAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZmlsbD0iIzk5OSI+5Zu+54mH6aKE6KeIPC90ZXh0Pjwvc3ZnPg=="
+                                        preview={{
+                                          mask: <span style={{ fontSize: 12 }}>预览</span>
+                                        }}
+                                      />
+                                    </div>
+                                  );
+                                })}
+                              </div>
+                            </Image.PreviewGroup>
+                            <div style={{ fontSize: 13, color: '#666', marginTop: 8 }}>共{evidenceImages.length}个文件</div>
+                          </>
+                        ) : (
+                          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
+                            <div style={{
+                              width: 100,
+                              height: 80,
+                              borderRadius: 4,
+                              overflow: 'hidden',
+                              border: '1px solid #e8e8e8',
+                              background: 'linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%)',
+                              display: 'flex',
+                              alignItems: 'center',
+                              justifyContent: 'center',
+                              color: '#999',
+                              fontSize: 13,
+                              fontWeight: 500,
+                            }}>
+                              暂无图片
+                            </div>
+                          </div>
+                        )}
+                      </td>
+                    </tr>
+                  </tbody>
+                </table>
+              </div>
+
+              {/* 操作按钮 */}
+              <div style={{
+                display: 'flex',
+                justifyContent: 'center',
+                gap: 16,
+                marginTop: 32,
+                paddingTop: 24,
+                borderTop: '1px solid #f0f0f0',
+              }}>
+                <Button
+                  type="primary"
+                  size="large"
+                  loading={auditLoading}
+                  onClick={handleAuditPass}
+                  style={{
+                    background: '#1A6FB8',
+                    borderColor: '#1A6FB8',
+                    minWidth: 120,
+                    height: 40,
+                    fontWeight: 500,
+                    boxShadow: '0 2px 0 rgba(0, 0, 0, 0.045)',
+                  }}
+                >
+                  审核通过
+                </Button>
+                <Button
+                  size="large"
+                  loading={auditLoading}
+                  onClick={handleOpenReturnModal}
+                  style={{
+                    background: 'white',
+                    color: '#1A6FB8',
+                    borderColor: '#1A6FB8',
+                    minWidth: 120,
+                    height: 40,
+                    fontWeight: 500,
+                    boxShadow: '0 2px 0 rgba(0, 0, 0, 0.015)',
+                  }}
+                >
+                  退回补充
+                </Button>
+              </div>
+            </div>
+          </div>
+        )}
+      </Modal>
+
+      {/* 退回补充子弹窗 */}
+      <Modal
+        title={
+          <div style={{ background: '#1A6FB8', margin: '-20px -24px', padding: '16px 24px', color: 'white' }}>
+            <span style={{ fontSize: 16, fontWeight: 600 }}>退回补充材料</span>
+          </div>
+        }
+        visible={returnModalVisible}
+        onCancel={handleCloseReturnModal}
+        footer={null}
+        width={480}
+        centered
+        destroyOnClose
+        bodyStyle={{ paddingTop: 24 }}
+      >
+        <div style={{ marginBottom: 20 }}>
+          <label style={{ display: 'block', fontWeight: 500, color: '#333', marginBottom: 8, fontSize: 14 }}>
+            退回意见:
+          </label>
+          <TextArea
+            value={auditRemark}
+            onChange={(e) => setAuditRemark(e.target.value)}
+            placeholder="请详细说明需要补充的材料内容及原因..."
+            rows={5}
+            style={{
+              borderRadius: 4,
+              resize: 'vertical',
+            }}
+          />
+        </div>
+        <div style={{
+          background: '#fafafa',
+          margin: '0 -24px -24px',
+          padding: '16px 24px',
+          display: 'flex',
+          justifyContent: 'flex-end',
+          gap: 12,
+        }}>
+          <Button onClick={handleCloseReturnModal} style={{ padding: '6px 16px' }}>
+            取消
+          </Button>
+          <Button
+            type="primary"
+            loading={auditLoading}
+            onClick={handleAuditReturn}
+            style={{ background: '#1A6FB8', borderColor: '#1A6FB8', padding: '6px 16px' }}
+          >
+            确认退回
+          </Button>
+        </div>
+      </Modal>
     </div>
   );
 };
@@ -525,6 +1254,193 @@
  * 调解协议
  */
 const AgreementSection = () => {
+  const { caseData } = useCaseData();
+  const [agreementContent, setAgreementContent] = useState('');
+  const [loading, setLoading] = useState(false);
+  const [error, setError] = useState(null);
+  const [editModalVisible, setEditModalVisible] = useState(false);
+  const [editContent, setEditContent] = useState('');
+  const [editLoading, setEditLoading] = useState(false);
+  const [actionLoading, setActionLoading] = useState({
+    confirm: false,
+    download: false,
+    regenerate: false,
+  });
+  const loadedRef = useRef(false);
+
+  // 获取 caseId
+  const caseId = caseData?.caseId || getMergedParams().caseId;
+
+  // 处理协议内容展示(纯文本,处理换行)
+  const renderAgreementContent = (content) => {
+    if (!content) return null;
+    // 处理 \n 换行,简单过滤 Markdown 符号
+    const lines = content.split('\n');
+    return lines.map((line, index) => {
+      // 简单过滤 ** 符号,保留文本
+      const cleanLine = line.replace(/\*\*/g, '');
+      if (!cleanLine.trim()) {
+        return <br key={index} />;
+      }
+      return (
+        <p key={index} style={{ margin: '8px 0', lineHeight: 1.6 }}>
+          {cleanLine}
+        </p>
+      );
+    });
+  };
+
+  // 首次加载协议内容
+  const loadAgreement = async () => {
+    if (!caseId) {
+      setError('缺少案件ID,无法加载协议');
+      return;
+    }
+    setLoading(true);
+    setError(null);
+    try {
+      const response = await MediationAgreementAPIService.generateAgreement(caseId);
+      if (response?.data?.agreeContent) {
+        setAgreementContent(response.data.agreeContent);
+      } else {
+        setError('协议内容为空');
+      }
+    } catch (err) {
+      console.error('加载协议失败:', err);
+      setError('加载协议失败,请稍后重试');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  // 组件挂载时加载协议
+  useEffect(() => {
+    if (caseId && !loadedRef.current) {
+      loadedRef.current = true;
+      loadAgreement();
+    }
+  }, [caseId]); // eslint-disable-line react-hooks/exhaustive-deps
+
+  // 确认协议
+  const handleConfirmAgreement = async () => {
+    if (!caseId) return;
+    setActionLoading(prev => ({ ...prev, confirm: true }));
+    try {
+      await MediationAgreementAPIService.confirmAgreement(caseId, 'mediator');
+      message.success('协议确认成功!');
+    } catch (err) {
+      console.error('确认协议失败:', err);
+      message.error('确认协议失败,请稍后重试');
+    } finally {
+      setActionLoading(prev => ({ ...prev, confirm: false }));
+    }
+  };
+
+  // 下载协议
+  const handleDownloadAgreement = async () => {
+    if (!caseId) return;
+    setActionLoading(prev => ({ ...prev, download: true }));
+    try {
+      await MediationAgreementAPIService.downloadAgreement(caseId);
+      message.success('协议下载成功!');
+    } catch (err) {
+      console.error('下载协议失败:', err);
+      message.error('下载协议失败,请稍后重试');
+    } finally {
+      setActionLoading(prev => ({ ...prev, download: false }));
+    }
+  };
+
+  // 重新生成协议
+  const handleRegenerateAgreement = async () => {
+    if (!caseId) return;
+    setActionLoading(prev => ({ ...prev, regenerate: true }));
+    try {
+      const response = await MediationAgreementAPIService.generateAgreement(caseId);
+      if (response?.data?.agreeContent) {
+        setAgreementContent(response.data.agreeContent);
+        message.success('协议重新生成成功!');
+      }
+    } catch (err) {
+      console.error('重新生成协议失败:', err);
+      message.error('重新生成协议失败,请稍后重试');
+    } finally {
+      setActionLoading(prev => ({ ...prev, regenerate: false }));
+    }
+  };
+
+  // 打开修改弹窗
+  const handleOpenEditModal = async () => {
+    if (!caseId) return;
+    setEditModalVisible(true);
+    setEditLoading(true);
+    try {
+      const response = await MediationAgreementAPIService.getAgreementDetail(caseId);
+      if (response?.data?.agreeContent) {
+        setEditContent(response.data.agreeContent);
+      }
+    } catch (err) {
+      console.error('获取协议内容失败:', err);
+      message.error('获取协议内容失败');
+    } finally {
+      setEditLoading(false);
+    }
+  };
+
+  // 关闭修改弹窗
+  const handleCloseEditModal = () => {
+    setEditModalVisible(false);
+    setEditContent('');
+  };
+
+  // 保存修改
+  const handleSaveEdit = async () => {
+    if (!caseId || !editContent.trim()) {
+      message.warning('协议内容不能为空');
+      return;
+    }
+    setEditLoading(true);
+    try {
+      await MediationAgreementAPIService.updateAgreement(caseId, editContent);
+      message.success('协议修改保存成功!');
+      handleCloseEditModal();
+      // 刷新父页面协议内容
+      const response = await MediationAgreementAPIService.generateAgreement(caseId);
+      if (response?.data?.agreeContent) {
+        setAgreementContent(response.data.agreeContent);
+      }
+    } catch (err) {
+      console.error('保存协议失败:', err);
+      message.error('保存协议失败,请稍后重试');
+    } finally {
+      setEditLoading(false);
+    }
+  };
+
+  // Loading 状态
+  if (loading) {
+    return (
+      <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 300 }}>
+        <Spin size="large" tip="正在生成调解协议..." />
+      </div>
+    );
+  }
+
+  // 错误状态
+  if (error) {
+    return (
+      <div style={{ textAlign: 'center', padding: 40, color: '#ff4d4f' }}>
+        <div style={{ fontSize: '1.2rem', marginBottom: 10 }}>
+          <i className="fas fa-exclamation-circle"></i> {error}
+        </div>
+        <button onClick={loadAgreement} style={{
+          marginTop: 15, padding: '8px 16px', backgroundColor: '#1890ff',
+          color: 'white', border: 'none', borderRadius: 4, cursor: 'pointer'
+        }}>重新加载</button>
+      </div>
+    );
+  }
+
   return (
     <div style={{
       background: '#f8f9fa',
@@ -533,56 +1449,15 @@
       maxHeight: 450,
       overflowY: 'auto',
     }}>
+      {/* 协议内容展示区域 */}
       <div style={{ lineHeight: 1.5, fontSize: '0.9rem' }}>
-        <div style={{ textAlign: 'center', color: 'var(--secondary-color)', fontSize: '1.2rem', marginBottom: 20, fontWeight: 700 }}>
-          李晓明与广东好又多贸易有限公司劳动争议调解协议书
-        </div>
-
-        <p><strong>甲方(申请人):</strong>李晓明</p>
-        <p><strong>乙方(被申请人):</strong>广东好又多贸易有限公司</p>
-
-        <p style={{ textIndent: '2em', marginTop: 15 }}>
-          甲方与乙方因劳动报酬支付问题发生争议,双方于2026年1月15日向"云小调"劳动争议AI调解智能体申请调解。经AI调解员调解,双方本着平等自愿、互谅互让的原则,达成如下调解协议:
-        </p>
-
-        <h3 style={{ color: 'var(--secondary-color)', margin: '15px 0 8px', fontSize: '1rem' }}>一、争议事项</h3>
-        <p style={{ textIndent: '2em' }}>甲方主张乙方拖欠2026年1月至3月共三个月工资、2026年第一季度绩效奖金以及解除劳动合同经济补偿金,合计人民币52,800元。</p>
-
-        <h3 style={{ color: 'var(--secondary-color)', margin: '15px 0 8px', fontSize: '1rem' }}>二、调解结果</h3>
-        <p style={{ textIndent: '2em' }}>经调解,双方达成一致意见如下:</p>
-        <ul style={{ paddingLeft: 30, marginBottom: 12 }}>
-          <li style={{ marginBottom: 6 }}>乙方同意向甲方支付劳动报酬共计人民币肆万肆仟元整(¥44,000)</li>
-          <li style={{ marginBottom: 6 }}>支付方式:分两期支付
-            <ul style={{ paddingLeft: 20 }}>
-              <li>第一期:人民币贰万贰仟元整(¥22,000),于2026年1月30日前支付</li>
-              <li>第二期:人民币贰万贰仟元整(¥22,000),于2026年2月28日前支付</li>
-            </ul>
-          </li>
-          <li style={{ marginBottom: 6 }}>支付账户:甲方指定的银行账户(账户信息另行提供)</li>
-        </ul>
-
-        <h3 style={{ color: 'var(--secondary-color)', margin: '15px 0 8px', fontSize: '1rem' }}>三、双方权利义务</h3>
-        <ul style={{ paddingLeft: 30, marginBottom: 12 }}>
-          <li style={{ marginBottom: 6 }}>乙方应按约定时间足额支付上述款项</li>
-          <li style={{ marginBottom: 6 }}>甲方收到全部款项后,双方劳动关系正式解除</li>
-          <li style={{ marginBottom: 6 }}>双方互不追究其他法律责任,本协议履行完毕后,争议事项一次性了结</li>
-        </ul>
-
-        {/* 签名区域 */}
-        <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 20, paddingTop: 15, borderTop: '1px solid var(--border-color)' }}>
-          <div style={{ textAlign: 'center', width: '45%' }}>
-            <div style={{ borderBottom: '1px solid var(--dark-color)', padding: '15px 0 5px', marginBottom: 5 }}></div>
-            <div>甲方(申请人):李晓明</div>
-            <div style={{ fontSize: '0.8rem', color: 'var(--gray-color)' }}>签字/盖章</div>
-            <div style={{ fontSize: '0.8rem', color: 'var(--gray-color)', marginTop: 5 }}>日期:2026年1月15日</div>
+        {agreementContent ? (
+          renderAgreementContent(agreementContent)
+        ) : (
+          <div style={{ textAlign: 'center', color: 'var(--gray-color)', padding: 40 }}>
+            暂无协议内容
           </div>
-          <div style={{ textAlign: 'center', width: '45%' }}>
-            <div style={{ borderBottom: '1px solid var(--dark-color)', padding: '15px 0 5px', marginBottom: 5 }}></div>
-            <div>乙方(被申请人):广东好又多贸易有限公司</div>
-            <div style={{ fontSize: '0.8rem', color: 'var(--gray-color)' }}>签字/盖章</div>
-            <div style={{ fontSize: '0.8rem', color: 'var(--gray-color)', marginTop: 5 }}>日期:2026年1月15日</div>
-          </div>
-        </div>
+        )}
       </div>
 
       {/* 操作按钮 */}
@@ -597,71 +1472,176 @@
         justifyContent: 'center',
         gap: 12,
       }}>
-        <button style={{
-          padding: '10px 20px',
-          border: '2px solid #c3e6cb',
-          borderRadius: 'var(--border-radius)',
-          fontWeight: 600,
-          fontSize: '0.9rem',
-          cursor: 'pointer',
-          display: 'flex',
-          alignItems: 'center',
-          gap: 6,
-          background: '#d4edda',
-          color: '#155724',
-        }}>
-          <i className="fas fa-check-circle"></i>
+        <button
+          onClick={handleConfirmAgreement}
+          disabled={actionLoading.confirm}
+          style={{
+            padding: '10px 20px',
+            border: '2px solid #c3e6cb',
+            borderRadius: 'var(--border-radius)',
+            fontWeight: 600,
+            fontSize: '0.9rem',
+            cursor: actionLoading.confirm ? 'not-allowed' : 'pointer',
+            display: 'flex',
+            alignItems: 'center',
+            gap: 6,
+            background: '#d4edda',
+            color: '#155724',
+            opacity: actionLoading.confirm ? 0.6 : 1,
+          }}>
+          <i className={actionLoading.confirm ? "fas fa-spinner fa-spin" : "fas fa-check-circle"}></i>
           确认协议
         </button>
-        <button style={{
-          padding: '10px 20px',
-          border: '2px solid #ffeaa7',
-          borderRadius: 'var(--border-radius)',
-          fontWeight: 600,
-          fontSize: '0.9rem',
-          cursor: 'pointer',
-          display: 'flex',
-          alignItems: 'center',
-          gap: 6,
-          background: '#fff3cd',
-          color: '#856404',
-        }}>
+        <button
+          onClick={handleOpenEditModal}
+          style={{
+            padding: '10px 20px',
+            border: '2px solid #ffeaa7',
+            borderRadius: 'var(--border-radius)',
+            fontWeight: 600,
+            fontSize: '0.9rem',
+            cursor: 'pointer',
+            display: 'flex',
+            alignItems: 'center',
+            gap: 6,
+            background: '#fff3cd',
+            color: '#856404',
+          }}>
           <i className="fas fa-edit"></i>
           修改协议
         </button>
-        <button style={{
-          padding: '10px 20px',
-          border: '2px solid #bbdefb',
-          borderRadius: 'var(--border-radius)',
-          fontWeight: 600,
-          fontSize: '0.9rem',
-          cursor: 'pointer',
-          display: 'flex',
-          alignItems: 'center',
-          gap: 6,
-          background: '#e3f2fd',
-          color: '#1565c0',
-        }}>
-          <i className="fas fa-download"></i>
+        <button
+          onClick={handleDownloadAgreement}
+          disabled={actionLoading.download}
+          style={{
+            padding: '10px 20px',
+            border: '2px solid #bbdefb',
+            borderRadius: 'var(--border-radius)',
+            fontWeight: 600,
+            fontSize: '0.9rem',
+            cursor: actionLoading.download ? 'not-allowed' : 'pointer',
+            display: 'flex',
+            alignItems: 'center',
+            gap: 6,
+            background: '#e3f2fd',
+            color: '#1565c0',
+            opacity: actionLoading.download ? 0.6 : 1,
+          }}>
+          <i className={actionLoading.download ? "fas fa-spinner fa-spin" : "fas fa-download"}></i>
           下载协议
         </button>
-        <button style={{
-          padding: '10px 20px',
-          border: '2px solid #bee5eb',
-          borderRadius: 'var(--border-radius)',
-          fontWeight: 600,
-          fontSize: '0.9rem',
-          cursor: 'pointer',
-          display: 'flex',
-          alignItems: 'center',
-          gap: 6,
-          background: '#d1ecf1',
-          color: '#0c5460',
-        }}>
-          <i className="fas fa-redo"></i>
+        <button
+          onClick={handleRegenerateAgreement}
+          disabled={actionLoading.regenerate}
+          style={{
+            padding: '10px 20px',
+            border: '2px solid #bee5eb',
+            borderRadius: 'var(--border-radius)',
+            fontWeight: 600,
+            fontSize: '0.9rem',
+            cursor: actionLoading.regenerate ? 'not-allowed' : 'pointer',
+            display: 'flex',
+            alignItems: 'center',
+            gap: 6,
+            background: '#d1ecf1',
+            color: '#0c5460',
+            opacity: actionLoading.regenerate ? 0.6 : 1,
+          }}>
+          <i className={actionLoading.regenerate ? "fas fa-spinner fa-spin" : "fas fa-redo"}></i>
           重新生成
         </button>
       </div>
+
+      {/* 修改调解协议书弹窗 */}
+      <Modal
+        title={null}
+        visible={editModalVisible}
+        onCancel={handleCloseEditModal}
+        footer={null}
+        width={1000}
+        centered
+        destroyOnClose
+        bodyStyle={{ padding: 0 }}
+      >
+        <div style={{ background: '#f5f7fa' }}>
+          {/* 头部 */}
+          <div style={{
+            background: '#1A6FB8',
+            color: 'white',
+            padding: '25px 30px',
+            borderBottom: '5px solid #0d4a8a',
+          }}>
+            <div style={{ fontSize: 24, fontWeight: 600, marginBottom: 10 }}>在线修改调解协议书</div>
+            <div style={{ fontSize: 16, opacity: 0.9 }}>编辑协议内容</div>
+          </div>
+
+          {/* 主体内容 */}
+          <div style={{ padding: '25px 30px', background: 'white' }}>
+            {/* 编辑提示 */}
+            <div style={{
+              fontSize: 14,
+              color: '#666',
+              marginBottom: 15,
+              padding: 10,
+              background: '#f0f8ff',
+              borderRadius: 5,
+              borderLeft: '3px solid #1A6FB8',
+            }}>
+              <strong>编辑提示:</strong>下方文本框中的协议内容可直接编辑修改。编辑完成后,请点击底部的"保存修改"按钮。
+            </div>
+
+            {/* 协议编辑区域 */}
+            <div style={{ marginBottom: 25 }}>
+              {editLoading ? (
+                <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 400 }}>
+                  <Spin size="large" tip="加载协议内容..." />
+                </div>
+              ) : (
+                <TextArea
+                  value={editContent}
+                  onChange={(e) => setEditContent(e.target.value)}
+                  style={{
+                    border: '1px solid #d0e3ff',
+                    borderRadius: 8,
+                    minHeight: 500,
+                    padding: 20,
+                    fontSize: 16,
+                    lineHeight: 1.8,
+                    background: '#f9fafc',
+                  }}
+                  placeholder="请输入协议内容..."
+                />
+              )}
+            </div>
+
+            {/* 操作按钮 */}
+            <div style={{
+              display: 'flex',
+              justifyContent: 'flex-end',
+              marginTop: 30,
+              paddingTop: 20,
+              borderTop: '1px solid #eaeaea',
+            }}>
+              <Button
+                type="primary"
+                size="large"
+                loading={editLoading}
+                onClick={handleSaveEdit}
+                style={{
+                  padding: '12px 36px',
+                  height: 'auto',
+                  fontWeight: 600,
+                  fontSize: 16,
+                  background: '#1A6FB8',
+                  borderColor: '#1A6FB8',
+                }}
+              >
+                保存修改
+              </Button>
+            </div>
+          </div>
+        </div>
+      </Modal>
     </div>
   );
 };

--
Gitblit v1.8.0