408 lines
20 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react';
import {
PackageCheck,
FileText,
Database,
FileSpreadsheet,
TrendingUp,
Download,
Eye,
ArrowLeft
} from 'lucide-react';
import { Scenario } from '../../types';
import { legacyOptimizationData } from '../../data/mockData';
type ReportType = 'summary' | 'inventory' | 'legacy-optimization' | 'potential-scenarios' | null;
interface DeliveryStepProps {
selectedScenarios: Scenario[];
}
export const DeliveryStep: React.FC<DeliveryStepProps> = ({ selectedScenarios }) => {
const [viewingReport, setViewingReport] = useState<ReportType>(null);
const [viewingInventoryId, setViewingInventoryId] = useState<number | null>(null);
// Report Detail View
if (viewingReport) {
return (
<div className="flex flex-col h-full bg-white">
<div className="p-6 border-b border-slate-200 flex items-center justify-between flex-none">
<div className="flex items-center">
<button
onClick={() => {
setViewingReport(null);
setViewingInventoryId(null);
}}
className="mr-4 text-slate-400 hover:text-slate-600"
>
<ArrowLeft size={20}/>
</button>
<h2 className="text-xl font-bold text-slate-900">
{viewingReport === 'summary' && '整体数据资产盘点工作总结'}
{viewingReport === 'inventory' && viewingInventoryId && `数据资产目录 - ${selectedScenarios.find(s => s.id === viewingInventoryId)?.name}`}
{viewingReport === 'legacy-optimization' && '存量数据应用场景优化建议'}
{viewingReport === 'potential-scenarios' && '潜在数据应用场景评估'}
</h2>
</div>
<button
onClick={() => {
// TODO: Implement download functionality based on report type
const reportName =
viewingReport === 'summary' ? '整体数据资产盘点工作总结' :
viewingReport === 'inventory' ? `数据资产目录-${selectedScenarios.find(s => s.id === viewingInventoryId)?.name}` :
viewingReport === 'legacy-optimization' ? '存量数据应用场景优化建议' :
'潜在数据应用场景评估';
console.log(`Download PDF: ${reportName}`);
}}
className="flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
<Download size={16} className="mr-2" />
PDF
</button>
</div>
<div className="flex-1 overflow-y-auto p-8 bg-slate-50">
<div className="max-w-4xl mx-auto bg-white rounded-lg shadow-sm border border-slate-200 p-8">
{viewingReport === 'summary' && (
<div className="space-y-6">
<div>
<h3 className="text-2xl font-bold text-slate-900 mb-4"></h3>
<p className="text-slate-700 leading-relaxed">
AI
PII
</p>
</div>
<div>
<h3 className="text-xl font-bold text-slate-900 mb-3"></h3>
<ul className="space-y-2 text-slate-700">
<li className="flex items-start">
<span className="text-blue-600 mr-2"></span>
<span> <strong>4 </strong> <strong>2,400 +</strong> </span>
</li>
<li className="flex items-start">
<span className="text-blue-600 mr-2"></span>
<span> PII <strong>3 </strong></span>
</li>
<li className="flex items-start">
<span className="text-blue-600 mr-2"></span>
<span> <strong>1 </strong></span>
</li>
<li className="flex items-start">
<span className="text-blue-600 mr-2"></span>
<span> <strong>{selectedScenarios.length} </strong></span>
</li>
</ul>
</div>
<div>
<h3 className="text-xl font-bold text-slate-900 mb-3"></h3>
<p className="text-slate-700 leading-relaxed">
</p>
</div>
</div>
)}
{viewingReport === 'inventory' && viewingInventoryId && (() => {
const scenario = selectedScenarios.find(s => s.id === viewingInventoryId);
if (!scenario) return null;
return (
<div className="space-y-6">
<div>
<h3 className="text-2xl font-bold text-slate-900 mb-4"></h3>
<p className="text-slate-600 mb-6"></p>
</div>
<div className="border border-slate-200 rounded-lg p-6">
<div className="flex items-center justify-between mb-4">
<h4 className="text-lg font-bold text-slate-900">{scenario.name}</h4>
<span className="px-3 py-1 bg-blue-100 text-blue-700 text-xs font-bold rounded-full">
{scenario.type}
</span>
</div>
<p className="text-slate-600 mb-4">{scenario.desc}</p>
<div>
<p className="text-sm font-bold text-slate-700 mb-2"></p>
<div className="flex flex-wrap gap-2">
{scenario.dependencies.map((dep, i) => (
<span key={i} className="px-2 py-1 bg-slate-100 text-slate-700 text-xs rounded border border-slate-200">
{dep}
</span>
))}
</div>
</div>
</div>
</div>
);
})()}
{viewingReport === 'legacy-optimization' && (
<div className="space-y-6">
<div>
<h3 className="text-2xl font-bold text-slate-900 mb-4"></h3>
<p className="text-slate-600 mb-6">
Step 3 AI
</p>
</div>
<div className="space-y-6">
{legacyOptimizationData.map((item) => (
<div key={item.id} className="border border-slate-200 rounded-lg p-6">
<div className="flex items-center justify-between mb-4">
<h4 className="text-xl font-bold text-slate-900">{item.title}</h4>
<span className={`px-3 py-1 rounded text-xs font-bold ${
item.impact === '高' ? 'bg-amber-100 text-amber-700' : 'bg-blue-100 text-blue-700'
}`}>
{item.impact}
</span>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="bg-red-50 p-4 rounded-lg border border-red-100">
<p className="text-xs font-bold text-red-700 mb-2"></p>
<p className="text-sm text-slate-700">{item.issue}</p>
</div>
<div className="bg-green-50 p-4 rounded-lg border border-green-100">
<p className="text-xs font-bold text-green-700 mb-2">AI </p>
<p className="text-sm text-slate-700">{item.suggestion}</p>
</div>
</div>
</div>
))}
</div>
</div>
)}
{viewingReport === 'potential-scenarios' && (
<div className="space-y-6">
<div>
<h3 className="text-2xl font-bold text-slate-900 mb-4"></h3>
<p className="text-slate-600 mb-6">
AI
</p>
</div>
<div className="space-y-4">
{selectedScenarios.map((scenario) => (
<div key={scenario.id} className="border border-slate-200 rounded-lg p-6">
<div className="flex items-center justify-between mb-3">
<h4 className="text-lg font-bold text-slate-900">{scenario.name}</h4>
<div className="flex items-center gap-2">
<span className="text-xs font-bold text-slate-500 border border-slate-200 px-2 py-1 rounded">
{scenario.type}
</span>
<span className={`text-xs font-bold px-2 py-1 rounded ${
scenario.impact === 'High' ? 'bg-green-100 text-green-700' : 'bg-amber-100 text-amber-700'
}`}>
{scenario.impact} Impact
</span>
</div>
</div>
<p className="text-slate-600 mb-4">{scenario.desc}</p>
<div>
<p className="text-sm font-bold text-slate-700 mb-2"></p>
<div className="flex flex-wrap gap-2">
{scenario.dependencies.map((dep, i) => (
<span key={i} className="px-2 py-1 bg-slate-100 text-slate-700 text-xs rounded border border-slate-200">
{dep}
</span>
))}
</div>
</div>
</div>
))}
</div>
</div>
)}
</div>
</div>
</div>
);
}
// Main Delivery View
return (
<div className="flex flex-col h-full bg-slate-50 overflow-y-auto animate-fade-in p-8 min-h-0">
<div className="text-center mb-10">
<div className="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center text-green-600 mx-auto mb-4 shadow-sm">
<PackageCheck size={36} />
</div>
<h2 className="text-3xl font-bold text-slate-900"></h2>
<p className="text-slate-500 mt-2"></p>
</div>
<div className="max-w-5xl mx-auto w-full space-y-6 mb-12">
{/* 整体数据资产盘点工作总结 */}
<div className="bg-white p-6 rounded-lg border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-start justify-between">
<div className="flex items-center flex-1">
<div className="p-3 bg-blue-100 rounded-lg text-blue-600 mr-4">
<FileText size={24}/>
</div>
<div className="flex-1">
<h3 className="font-bold text-slate-900 text-lg mb-1"></h3>
<p className="text-sm text-slate-500"></p>
</div>
</div>
<div className="flex items-center gap-2">
<button
onClick={() => setViewingReport('summary')}
className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center"
>
<Eye size={16} className="mr-2" />
线
</button>
<button
onClick={(e) => {
e.stopPropagation();
// TODO: Implement download functionality
console.log('Download: 整体数据资产盘点工作总结');
}}
className="p-2 text-slate-400 hover:text-blue-600 transition-colors"
title="下载 PDF"
>
<Download size={18} />
</button>
</div>
</div>
</div>
{/* 数据资产目录 - 多个 */}
<div>
<h3 className="text-sm font-bold text-slate-500 uppercase tracking-wider mb-4 flex items-center">
<Database size={16} className="mr-2"/>
</h3>
{selectedScenarios.length === 0 ? (
<div className="bg-slate-50 border border-slate-200 rounded-lg p-6 text-center">
<p className="text-sm text-slate-500"></p>
</div>
) : (
<div className="space-y-4">
{selectedScenarios.map((scenario, idx) => (
<div key={scenario.id} className="bg-white p-6 rounded-lg border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-start justify-between">
<div className="flex items-center flex-1">
<div className="p-3 bg-green-50 rounded-lg text-green-600 mr-4">
<FileSpreadsheet size={24}/>
</div>
<div className="flex-1">
<h4 className="font-bold text-slate-900 mb-1"> - {scenario.name}</h4>
<p className="text-xs text-slate-500"></p>
</div>
</div>
<div className="flex items-center gap-2">
<button
onClick={() => {
setViewingInventoryId(scenario.id);
setViewingReport('inventory');
}}
className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 flex items-center"
>
<Eye size={16} className="mr-2" />
线
</button>
<button
onClick={(e) => {
e.stopPropagation();
console.log(`Download: 数据资产目录-${scenario.name}`);
}}
className="p-2 text-slate-400 hover:text-green-600 transition-colors"
title="下载 Excel"
>
<Download size={18} />
</button>
</div>
</div>
</div>
))}
</div>
)}
</div>
{/* 存量数据应用场景优化建议 */}
<div className="bg-white p-6 rounded-lg border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-start justify-between">
<div className="flex items-center flex-1">
<div className="p-3 bg-amber-50 rounded-lg text-amber-600 mr-4">
<TrendingUp size={24}/>
</div>
<div className="flex-1">
<h3 className="font-bold text-slate-900 text-lg mb-1"></h3>
<p className="text-sm text-slate-500"> AI </p>
</div>
</div>
<div className="flex items-center gap-2">
<button
onClick={() => setViewingReport('legacy-optimization')}
className="px-4 py-2 bg-amber-600 text-white rounded-lg hover:bg-amber-700 flex items-center"
>
<Eye size={16} className="mr-2" />
线
</button>
<button
onClick={(e) => {
e.stopPropagation();
console.log('Download: 存量数据应用场景优化建议');
}}
className="p-2 text-slate-400 hover:text-amber-600 transition-colors"
title="下载 PDF"
>
<Download size={18} />
</button>
</div>
</div>
</div>
{/* 潜在数据应用场景评估 */}
{selectedScenarios.length > 0 && (
<div className="bg-white p-6 rounded-lg border border-slate-200 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-start justify-between">
<div className="flex items-center flex-1">
<div className="p-3 bg-purple-50 rounded-lg text-purple-600 mr-4">
<TrendingUp size={24}/>
</div>
<div className="flex-1">
<h3 className="font-bold text-slate-900 text-lg mb-1"></h3>
<p className="text-sm text-slate-500">AI </p>
</div>
</div>
<div className="flex items-center gap-2">
<button
onClick={() => setViewingReport('potential-scenarios')}
className="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 flex items-center"
>
<Eye size={16} className="mr-2" />
线
</button>
<button
onClick={(e) => {
e.stopPropagation();
console.log('Download: 潜在数据应用场景评估');
}}
className="p-2 text-slate-400 hover:text-purple-600 transition-colors"
title="下载 PDF"
>
<Download size={18} />
</button>
</div>
</div>
</div>
)}
</div>
<div className="max-w-4xl mx-auto w-full text-center">
<button
onClick={() => {
// TODO: Implement batch download functionality
if (confirm('确认下载所有交付物?下载后系统将自动锁定本项目的所有编辑权限 (Audit Lock)。')) {
console.log('Download all deliverables as ZIP');
}
}}
className="px-8 py-3 bg-slate-900 text-white rounded-lg font-bold shadow-lg hover:bg-slate-800 transition-transform hover:scale-105 flex items-center mx-auto"
>
<PackageCheck size={20} className="mr-2"/>
(Zip)
</button>
<p className="text-xs text-slate-400 mt-4">
操作提示: 确认下载后 (Audit Lock)
</p>
</div>
</div>
);
};