From cd65fdeabc462afd4fe99e4c789a243bf9b64ee6 Mon Sep 17 00:00:00 2001
From: shimai <shimai@example.com>
Date: Fri, 27 Feb 2026 16:28:27 +0800
Subject: [PATCH] fix:修复调解协议无法下载
---
web-app/src/components/dashboard/TabContainer.jsx | 81 +++++++++++++++++++++++++++++++++++++---
1 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/web-app/src/components/dashboard/TabContainer.jsx b/web-app/src/components/dashboard/TabContainer.jsx
index b16768d..639d7b2 100644
--- a/web-app/src/components/dashboard/TabContainer.jsx
+++ b/web-app/src/components/dashboard/TabContainer.jsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useRef } 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';
@@ -6,16 +6,25 @@
import MediationAgreementAPIService from '../../services/MediationAgreementAPIService';
import { getMergedParams } from '../../utils/urlParams';
import { message, Spin, Tag, Modal, Button, Input, Image } from 'antd';
+import config from '../../config/env';
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' },
@@ -76,7 +85,7 @@
</div>
</div>
);
-};
+});
/**
* 调解数据看板
@@ -1282,6 +1291,32 @@
});
};
+ const resolveDownloadFileName = (contentDisposition) => {
+ if (!contentDisposition) return '';
+ const utf8Match = contentDisposition.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
+ if (utf8Match?.[1]) {
+ try {
+ return decodeURIComponent(utf8Match[1]);
+ } catch (err) {
+ return utf8Match[1];
+ }
+ }
+ const fileNameMatch = contentDisposition.match(/filename\s*=\s*"?([^"]+)"?/i);
+ if (fileNameMatch?.[1]) return fileNameMatch[1];
+ return '';
+ };
+
+ const triggerFileDownload = (blob, fileName) => {
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = fileName;
+ document.body.appendChild(link);
+ link.click();
+ link.remove();
+ window.URL.revokeObjectURL(url);
+ };
+
// 首次加载协议内容
const loadAgreement = async () => {
if (!caseId) {
@@ -1333,11 +1368,45 @@
if (!caseId) return;
setActionLoading(prev => ({ ...prev, download: true }));
try {
- await MediationAgreementAPIService.downloadAgreement(caseId);
- message.success('协议下载成功!');
+ const token = localStorage.getItem('access_token');
+ const response = await fetch(`${config.baseURL}/api/v1/medi-agreement/download`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ ...(token ? { Authorization: `Bearer ${token}` } : {})
+ },
+ body: JSON.stringify({ caseId }),
+ credentials: config.withCredentials ? 'include' : 'omit'
+ });
+
+ const contentType = response.headers.get('Content-Type') || '';
+ if (contentType.includes('application/pdf')) {
+ if (!response.ok) {
+ throw new Error('下载协议失败,请稍后重试');
+ }
+ const blob = await response.blob();
+ const contentDisposition = response.headers.get('Content-Disposition') || '';
+ const fileName = resolveDownloadFileName(contentDisposition) || '调解协议书.pdf';
+ triggerFileDownload(blob, fileName);
+ message.success('协议下载成功!');
+ return;
+ }
+
+ const data = await response.json();
+ if (data?.code !== 200 && data?.code !== 201) {
+ throw new Error(data?.message || '下载协议失败,请稍后重试');
+ }
+ if (data?.data?.needConfirm || data?.message === '待确认') {
+ message.warning('协议待确认,请先确认协议');
+ return;
+ }
+ if (data?.data?.agreeContent) {
+ setAgreementContent(data.data.agreeContent);
+ }
+ message.success(data?.message || '已返回协议内容');
} catch (err) {
console.error('下载协议失败:', err);
- message.error('下载协议失败,请稍后重试');
+ message.error(err?.message || '下载协议失败,请稍后重试');
} finally {
setActionLoading(prev => ({ ...prev, download: false }));
}
--
Gitblit v1.8.0