"use client"; import { useState, useRef, useEffect } from "react"; import { streamChat, type ChatMessage } from "@/lib/api"; interface DisplayMessage { role: "user" | "assistant"; content: string; } const QUICK_QUESTIONS = [ "今日市场怎么样?", "有哪些推荐股票?", "哪些板块最热门?", ]; export default function ChatPage() { const [messages, setMessages] = useState([]); const [input, setInput] = useState(""); const [streaming, setStreaming] = useState(false); const [status, setStatus] = useState(""); const scrollRef = useRef(null); const inputRef = useRef(null); const scrollToBottom = () => { scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: "smooth", }); }; useEffect(() => { scrollToBottom(); }, [messages, status]); const sendMessage = async (text: string) => { if (!text.trim() || streaming) return; const userMsg: DisplayMessage = { role: "user", content: text.trim() }; const newMessages = [...messages, userMsg]; setMessages(newMessages); setInput(""); setStreaming(true); setStatus(""); // Add empty assistant message for streaming setMessages([...newMessages, { role: "assistant", content: "" }]); try { const chatMessages: ChatMessage[] = newMessages.map((m) => ({ role: m.role, content: m.content, })); let fullContent = ""; for await (const event of streamChat(chatMessages)) { if (event.type === "status") { setStatus(event.content); } else if (event.type === "content") { fullContent += event.content; setMessages([ ...newMessages, { role: "assistant", content: fullContent }, ]); setStatus(""); } } } catch (e) { console.error("Chat error:", e); setMessages([ ...newMessages, { role: "assistant", content: "连接失败,请检查网络后重试。" }, ]); } finally { setStreaming(false); setStatus(""); } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendMessage(input); } }; return (
{/* Header */}

AI 投资顾问

基于实时市场数据的智能问答

{messages.length > 0 && ( )}
{/* Messages */}
{messages.length === 0 ? (

有什么想了解的?

我可以查询市场数据,分析个股走势,解读板块热度

{QUICK_QUESTIONS.map((q) => ( ))}
) : ( <> {messages.map((msg, i) => (
{msg.role === "assistant" ? ( msg.content ? (
) : ( {status || "思考中..."} ) ) : ( {msg.content} )} {streaming && i === messages.length - 1 && msg.role === "assistant" && msg.content && ( )}
))} {/* Status indicator during tool calls */} {streaming && status && messages[messages.length - 1]?.content && (
{status}
)} )}
{/* Input */}