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:
167
frontend-v2/src/modules/dc/pages/tool-b/index.tsx
Normal file
167
frontend-v2/src/modules/dc/pages/tool-b/index.tsx
Normal file
@@ -0,0 +1,167 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import Step1Upload from './Step1Upload';
|
||||
import Step2Schema from './Step2Schema';
|
||||
import Step3Processing from './Step3Processing';
|
||||
import Step4Verify from './Step4Verify';
|
||||
import Step5Result from './Step5Result';
|
||||
import StepIndicator from './components/StepIndicator';
|
||||
import { Bot, Split, ArrowLeft } from 'lucide-react';
|
||||
|
||||
export type Step = 'upload' | 'schema' | 'processing' | 'verify' | 'result';
|
||||
|
||||
export interface ExtractionField {
|
||||
id: string;
|
||||
name: string;
|
||||
desc: string;
|
||||
width?: string;
|
||||
}
|
||||
|
||||
export interface ToolBState {
|
||||
// Step 1
|
||||
fileName: string;
|
||||
fileKey: string;
|
||||
selectedColumn: string;
|
||||
healthCheckResult: {
|
||||
status: 'unknown' | 'good' | 'bad';
|
||||
emptyRate?: number;
|
||||
avgLength?: number;
|
||||
totalRows?: number;
|
||||
estimatedTokens?: number;
|
||||
message?: string;
|
||||
};
|
||||
|
||||
// Step 2
|
||||
diseaseType: string;
|
||||
reportType: string;
|
||||
fields: ExtractionField[];
|
||||
|
||||
// Step 3
|
||||
taskId?: string;
|
||||
progress: number;
|
||||
|
||||
// Step 4
|
||||
rows: any[];
|
||||
|
||||
// Step 5
|
||||
resultFileUrl?: string;
|
||||
}
|
||||
|
||||
const ToolBModule: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const [currentStep, setCurrentStep] = useState<Step>('upload');
|
||||
const [state, setState] = useState<ToolBState>({
|
||||
fileName: '',
|
||||
fileKey: '',
|
||||
selectedColumn: '',
|
||||
healthCheckResult: { status: 'unknown' },
|
||||
diseaseType: 'lung_cancer',
|
||||
reportType: 'pathology',
|
||||
fields: [],
|
||||
progress: 0,
|
||||
rows: [],
|
||||
});
|
||||
|
||||
const updateState = (updates: Partial<ToolBState>) => {
|
||||
setState(prev => ({ ...prev, ...updates }));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50 font-sans text-slate-800 p-6">
|
||||
<div className="max-w-7xl mx-auto bg-white rounded-2xl shadow-sm border border-slate-200 min-h-[800px] flex flex-col overflow-hidden">
|
||||
|
||||
{/* Header */}
|
||||
<div className="px-8 py-5 border-b border-slate-100 flex justify-between items-center bg-gradient-to-r from-purple-50 via-white to-white">
|
||||
<div className="flex items-center gap-4">
|
||||
<button
|
||||
onClick={() => navigate('/data-cleaning')}
|
||||
className="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-white border border-slate-200 hover:border-slate-300 text-slate-600 hover:text-slate-900 transition-all shadow-sm hover:shadow"
|
||||
title="返回数据清洗工作台"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
<span className="text-sm font-medium">返回工作台</span>
|
||||
</button>
|
||||
<div className="h-8 w-px bg-slate-200"></div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center text-purple-600">
|
||||
<Bot className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-xl font-bold text-slate-900">病历结构化机器人</h1>
|
||||
<div className="flex items-center gap-2 text-xs text-slate-500">
|
||||
<span className="flex items-center gap-1">
|
||||
<Split className="w-3 h-3" /> 双模型交叉验证
|
||||
</span>
|
||||
<span>•</span>
|
||||
<span>DeepSeek-V3 & Qwen-Max</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 状态指示器 */}
|
||||
{currentStep === 'verify' && (
|
||||
<div className="flex gap-3">
|
||||
<div className="flex items-center gap-1.5 px-3 py-1 bg-blue-50 text-blue-700 text-xs rounded-full border border-blue-100 font-medium">
|
||||
<div className="w-2 h-2 rounded-full bg-blue-500"></div> DeepSeek
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5 px-3 py-1 bg-orange-50 text-orange-700 text-xs rounded-full border border-orange-100 font-medium">
|
||||
<div className="w-2 h-2 rounded-full bg-orange-500"></div> Qwen
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Step Indicator */}
|
||||
<div className="pt-6 pb-2">
|
||||
<StepIndicator currentStep={currentStep} />
|
||||
</div>
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="flex-1 px-8 pb-8 relative overflow-hidden flex flex-col">
|
||||
{currentStep === 'upload' && (
|
||||
<Step1Upload
|
||||
state={state}
|
||||
updateState={updateState}
|
||||
onNext={() => setCurrentStep('schema')}
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentStep === 'schema' && (
|
||||
<Step2Schema
|
||||
state={state}
|
||||
updateState={updateState}
|
||||
onNext={() => setCurrentStep('processing')}
|
||||
onPrev={() => setCurrentStep('upload')}
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentStep === 'processing' && (
|
||||
<Step3Processing
|
||||
state={state}
|
||||
updateState={updateState}
|
||||
onComplete={() => setCurrentStep('verify')}
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentStep === 'verify' && (
|
||||
<Step4Verify
|
||||
state={state}
|
||||
updateState={updateState}
|
||||
onComplete={() => setCurrentStep('result')}
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentStep === 'result' && (
|
||||
<Step5Result
|
||||
state={state}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ToolBModule;
|
||||
|
||||
Reference in New Issue
Block a user