From 9167ea7dca015c7ff1f35fa7eb63161fe10eac7b Mon Sep 17 00:00:00 2001
From: tony.cheng <chengmingwei_1984122@126.com>
Date: Wed, 04 Mar 2026 12:09:24 +0800
Subject: [PATCH] fix: 修正下载协议功能,正确处理PDF文件流
---
web-app/src/components/dashboard/TabContainer.jsx | 98 +++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 90 insertions(+), 8 deletions(-)
diff --git a/web-app/src/components/dashboard/TabContainer.jsx b/web-app/src/components/dashboard/TabContainer.jsx
index b16768d..ed02399 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';
@@ -11,11 +11,19 @@
/**
* 选项卡容器组件 - 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 +84,7 @@
</div>
</div>
);
-};
+});
/**
* 调解数据看板
@@ -477,7 +485,7 @@
// 使用getMergedParams获取参数(URL参数优先,默认值兜底)
const params = getMergedParams();
const caseId = params.caseId;
- const caseType = params.caseTypeFirst;
+ const caseType = params.caseType ||params.caseTypeFirst;
const platformCode = params.platform_code;
console.log('EvidenceBoard loadData params:', { caseId, caseType, platformCode });
@@ -1082,9 +1090,55 @@
<Image.PreviewGroup>
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
{evidenceImages.map((img, index) => {
+ // 判断 show_url 是否以 http 开头
+ const isFullUrl = img.show_url && img.show_url.startsWith('http');
+ // 如果是完整URL直接使用,否则拼接 platformUrl
const imgUrl = img.show_url
- ? (platformUrl ? `${platformUrl}/${img.show_url}` : img.show_url)
+ ? (isFullUrl ? img.show_url : (platformUrl ? `${platformUrl}/${img.show_url}` : img.show_url))
: '';
+ // 获取文件名:true_name 为空时取 file_name
+ const rawFileName = img.true_name || img.file_name || `材料${index + 1}`;
+ // 获取文件类型后缀
+ const suffix = img.suffix || '';
+ // 检查文件名是否已包含后缀,避免重复
+ const fileName = suffix && rawFileName.toLowerCase().endsWith(`.${suffix.toLowerCase()}`)
+ ? rawFileName
+ : (suffix ? `${rawFileName}.${suffix}` : rawFileName);
+ const isPdf = suffix.toLowerCase() === 'pdf';
+
+ if (isPdf) {
+ // PDF文件:直接打开PDF链接
+ 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',
+ background: '#f5f5f5',
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ }}
+ onClick={() => {
+ // 直接打开PDF
+ window.open(imgUrl, '_blank');
+ }}
+ >
+ <i className="fas fa-file-pdf" style={{ fontSize: 32, color: '#ff4d4f' }} />
+ <span style={{ fontSize: 10, color: '#666', marginTop: 4, maxWidth: 90, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
+ {fileName}
+ </span>
+ </div>
+ );
+ }
+
+ // 图片文件:使用图片预览
return (
<div
key={img.file_id || img.id || index}
@@ -1100,11 +1154,18 @@
>
<Image
src={imgUrl}
- alt={img.file_name || `材料${index + 1}`}
+ alt={fileName}
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
fallback="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjgwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iODAiIGZpbGw9IiNmNWY1ZjUiLz48dGV4dCB4PSI1MCIgeT0iNDAiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZmlsbD0iIzk5OSI+5Zu+54mH6aKE6KeIPC90ZXh0Pjwvc3ZnPg=="
preview={{
- mask: <span style={{ fontSize: 12 }}>预览</span>
+ mask: (
+ <span style={{ fontSize: 12, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
+ <span>预览</span>
+ <span style={{ fontSize: 10, marginTop: 2, maxWidth: 80, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
+ {fileName}
+ </span>
+ </span>
+ )
}}
/>
</div>
@@ -1333,7 +1394,28 @@
if (!caseId) return;
setActionLoading(prev => ({ ...prev, download: true }));
try {
- await MediationAgreementAPIService.downloadAgreement(caseId);
+ // 调用API获取PDF文件流
+ const response = await MediationAgreementAPIService.downloadAgreement(caseId);
+
+ // 创建Blob对象(PDF格式)
+ const blob = new Blob([response.data], {
+ type: 'application/pdf'
+ });
+
+ // 创建下载链接
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = `调解协议_${caseId}.pdf`;
+
+ // 触发下载
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+
+ // 清理URL对象
+ window.URL.revokeObjectURL(url);
+
message.success('协议下载成功!');
} catch (err) {
console.error('下载协议失败:', err);
--
Gitblit v1.8.0