import { useState, useEffect, useRef, useCallback } from 'react'
import { useSearchParams } from 'react-router-dom'
import { Card, Progress, Badge, Empty, Button, Result, message } from 'antd'
import { CheckCircleOutlined, SyncOutlined, CloseCircleOutlined } from '@ant-design/icons'
const ANALYSIS_STAGES = [
{ key: 'analysts', label: '分析师团队' },
{ key: 'research', label: '研究员辩论' },
{ key: 'trading', label: '交易员' },
{ key: 'risk', label: '风险管理' },
{ key: 'portfolio', label: '组合经理' },
]
export default function AnalysisMonitor() {
const [searchParams] = useSearchParams()
const taskId = searchParams.get('task_id')
const [task, setTask] = useState(null)
const [wsConnected, setWsConnected] = useState(false)
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const wsRef = useRef(null)
const fetchInitialState = useCallback(async () => {
if (!taskId) return
setLoading(true)
try {
const res = await fetch(`/api/analysis/status/${taskId}`)
if (!res.ok) throw new Error('获取任务状态失败')
const data = await res.json()
setTask(data)
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}, [taskId])
const connectWebSocket = useCallback(() => {
if (wsRef.current) wsRef.current.close()
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const host = window.location.host
const ws = new WebSocket(`${protocol}//${host}/ws/analysis/${taskId}`)
ws.onopen = () => {
setWsConnected(true)
setError(null)
}
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
if (data.type === 'progress') {
const { type, ...taskData } = data
setTask(taskData)
}
} catch (e) {
// ignore parse errors
}
}
ws.onerror = () => {
setError('WebSocket连接失败')
setWsConnected(false)
}
ws.onclose = () => {
setWsConnected(false)
}
wsRef.current = ws
}, [taskId])
useEffect(() => {
if (!taskId) return
fetchInitialState()
connectWebSocket()
return () => {
if (wsRef.current) wsRef.current.close()
}
}, [taskId, fetchInitialState, connectWebSocket])
const formatTime = (seconds) => {
const mins = Math.floor(seconds / 60)
const secs = seconds % 60
return `${mins}:${secs.toString().padStart(2, '0')}`
}
const getStageIcon = (status) => {
switch (status) {
case 'completed':
return