feat(dc): Complete Tool B frontend development with UI optimization

- Implement Tool B 5-step workflow (upload, schema, processing, verify, result)
- Add back navigation button to Portal
- Optimize Step 2 field list styling to match prototype
- Fix step 3 label: 'dual-blind' to 'dual-model'
- Create API service layer with 7 endpoints
- Integrate Tool B route into DC module
- Add comprehensive TypeScript types

Components (~1100 lines):
- index.tsx: Main Tool B entry with state management
- Step1Upload.tsx: File upload and health check
- Step2Schema.tsx: Smart template configuration
- Step3Processing.tsx: Dual-model extraction progress
- Step4Verify.tsx: Conflict verification workbench
- Step5Result.tsx: Result display
- StepIndicator.tsx: Step progress component
- api/toolB.ts: API service layer

Status: Frontend complete, ready for API integration
This commit is contained in:
2025-12-03 09:36:35 +08:00
parent 33db2687b9
commit 5f1e7af92c
47 changed files with 2757 additions and 10 deletions

View File

@@ -0,0 +1,75 @@
import React, { useEffect } from 'react';
import { ToolBState } from './index';
interface Step3ProcessingProps {
state: ToolBState;
updateState: (updates: Partial<ToolBState>) => void;
onComplete: () => void;
}
const Step3Processing: React.FC<Step3ProcessingProps> = ({ state, updateState, onComplete }) => {
useEffect(() => {
// 模拟处理进度
const timer = setInterval(() => {
updateState({ progress: Math.min(state.progress + 2, 100) });
if (state.progress >= 100) {
clearInterval(timer);
setTimeout(onComplete, 800);
}
}, 100);
return () => clearInterval(timer);
}, [state.progress, updateState, onComplete]);
return (
<div className="flex flex-col items-center justify-center h-full animate-in fade-in duration-500 mt-10">
<div className="relative mb-8">
<div className="w-24 h-24 rounded-full border-4 border-slate-100"></div>
<div className="absolute inset-0 w-24 h-24 rounded-full border-4 border-purple-600 border-t-transparent animate-spin"></div>
<div className="absolute inset-0 flex items-center justify-center gap-1">
<div className="w-3 h-3 rounded-full bg-blue-500 animate-bounce" style={{ animationDelay: '0s' }}></div>
<div className="w-3 h-3 rounded-full bg-orange-500 animate-bounce" style={{ animationDelay: '0.2s' }}></div>
</div>
</div>
<h3 className="text-xl font-bold text-slate-900 mb-2">...</h3>
<div className="w-96 bg-slate-100 rounded-full h-2 overflow-hidden mb-6">
<div
className="bg-purple-600 h-full transition-all duration-300 ease-out"
style={{ width: `${state.progress}%` }}
></div>
</div>
<div className="w-full max-w-lg bg-slate-50 rounded-lg border border-slate-200 p-4 font-mono text-xs h-40 overflow-y-auto shadow-inner">
<div className="mb-1 text-slate-600 flex gap-2">
<span className="text-slate-400">[{new Date().toLocaleTimeString()}]</span>
<span> (DeepSeek-V3 & Qwen-Max)...</span>
</div>
<div className="mb-1 text-slate-600 flex gap-2">
<span className="text-slate-400">[{new Date().toLocaleTimeString()}]</span>
<span>PII ...</span>
</div>
{state.progress > 40 && (
<div className="mb-1 text-slate-600 flex gap-2">
<span className="text-slate-400">[{new Date().toLocaleTimeString()}]</span>
<span>DeepSeek: 提取进度 {state.progress}%</span>
</div>
)}
{state.progress > 45 && (
<div className="mb-1 text-slate-600 flex gap-2">
<span className="text-slate-400">[{new Date().toLocaleTimeString()}]</span>
<span>Qwen: 提取进度 {state.progress}%</span>
</div>
)}
{state.progress > 80 && (
<div className="mb-1 text-slate-600 flex gap-2">
<span className="text-slate-400">[{new Date().toLocaleTimeString()}]</span>
<span> (Cross-Validation)...</span>
</div>
)}
<div className="animate-pulse text-purple-500">_</div>
</div>
</div>
);
};
export default Step3Processing;