Fundamental_Analysis/frontend/src/app/report/[symbol]/page.tsx
Lv, Qi d28f3c5266 feat: update analysis workflow and fix LLM client connection issues
- Enhance LlmClient to handle malformed URLs and HTML error responses
- Improve logging in report-generator-service worker
- Update frontend API routes and hooks for analysis
- Update various service configurations and persistence logic
2025-11-19 17:30:52 +08:00

144 lines
4.6 KiB
TypeScript

'use client';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
import { useReportData } from './hooks/useReportData';
import { useAnalysisRunner } from './hooks/useAnalysisRunner';
import { ReportHeader } from './components/ReportHeader';
import { TaskStatus } from './components/TaskStatus';
import { StockChart } from './components/StockChart';
import { FinancialTable } from './components/FinancialTable';
import { AnalysisContent } from './components/AnalysisContent';
import { ExecutionDetails } from './components/ExecutionDetails';
export default function ReportPage() {
const {
unifiedSymbol,
displayMarket,
normalizedMarket,
marketParam,
financials,
isLoading,
error,
snapshot,
snapshotLoading,
realtime,
realtimeLoading,
realtimeError,
financialConfig,
templateSets,
} = useReportData();
const {
activeAnalysisConfig,
analysisTypes,
analysisStates,
analysisRecords,
currentAnalysisTask,
triggerAnalysis,
triggering,
requestId,
taskProgress,
startTime,
elapsedSeconds,
completionProgress,
totalElapsedMs,
stopAll,
continuePending,
retryAnalysis,
hasRunningTask,
isAnalysisRunning,
selectedTemplateId,
setSelectedTemplateId,
} = useAnalysisRunner(financials, financialConfig, normalizedMarket, unifiedSymbol, isLoading, error, templateSets);
return (
<div className="space-y-4">
<div className="flex items-stretch justify-between gap-4">
<ReportHeader
unifiedSymbol={unifiedSymbol}
displayMarket={displayMarket}
isLoading={isLoading}
financials={financials}
snapshot={snapshot}
snapshotLoading={snapshotLoading}
triggering={triggering}
hasRunningTask={hasRunningTask}
isAnalysisRunning={isAnalysisRunning}
onStartAnalysis={triggerAnalysis}
onStopAnalysis={stopAll}
onContinueAnalysis={continuePending}
templateSets={templateSets}
selectedTemplateId={selectedTemplateId}
onSelectTemplate={setSelectedTemplateId}
/>
<TaskStatus
requestId={requestId}
taskProgress={taskProgress}
startTime={startTime}
elapsedSeconds={elapsedSeconds}
completionProgress={completionProgress}
currentAnalysisTask={currentAnalysisTask}
analysisConfig={activeAnalysisConfig}
/>
</div>
<Tabs defaultValue="chart" className="mt-4">
<TabsList className="flex-wrap">
<TabsTrigger value="chart"></TabsTrigger>
<TabsTrigger value="financial"></TabsTrigger>
{analysisTypes.map(type => (
<TabsTrigger key={type} value={type}>
{type === 'company_profile' ? '公司简介' : (activeAnalysisConfig?.analysis_modules?.[type]?.name || type)}
</TabsTrigger>
))}
<TabsTrigger value="execution"></TabsTrigger>
</TabsList>
<TabsContent value="chart">
<StockChart
unifiedSymbol={unifiedSymbol}
marketParam={marketParam}
realtime={realtime}
realtimeLoading={realtimeLoading}
realtimeError={realtimeError}
/>
</TabsContent>
<TabsContent value="financial">
<FinancialTable
financials={financials}
isLoading={isLoading}
error={error}
financialConfig={activeAnalysisConfig}
/>
</TabsContent>
{analysisTypes.map(analysisType => (
<TabsContent key={analysisType} value={analysisType}>
<AnalysisContent
analysisType={analysisType}
state={analysisStates[analysisType] || { content: '', loading: false, error: null }}
financials={financials}
analysisConfig={activeAnalysisConfig}
retryAnalysis={retryAnalysis}
currentAnalysisTask={currentAnalysisTask}
/>
</TabsContent>
))}
<TabsContent value="execution">
<ExecutionDetails
financials={financials}
isLoading={isLoading}
error={error}
analysisRecords={analysisRecords}
currentAnalysisTask={currentAnalysisTask}
totalElapsedMs={totalElapsedMs}
retryAnalysis={retryAnalysis}
/>
</TabsContent>
</Tabs>
</div>
);
}