"use client";
import { FormEvent, useEffect, useMemo, useRef, useState } from "react";
import { BookOpenCheck, Clock3, Home, MessageCircle, SendHorizonal, Settings, ShieldCheck, UserRound } from "lucide-react";
import { api } from "@/lib/api";
import type { CallableQAItem } from "@/lib/types";
import {
findQaAnswer,
initialMessages,
mockCallableQa,
suggestedQuestions,
type ChatMessage
} from "@/lib/h5MockQa";
import ChatBubble from "./ChatBubble";
import MockAuthPanel, { type MockUser } from "./MockAuthPanel";
type MobileTab = "qa" | "history" | "me";
function nowText() {
return new Intl.DateTimeFormat("zh-CN", {
hour: "2-digit",
minute: "2-digit",
hour12: false
}).format(new Date());
}
function buildAnswerMessage(question: string, qa: CallableQAItem): ChatMessage {
return {
id: `assistant-${Date.now()}`,
role: "assistant",
content: qa.standard_answer,
source: `${qa.standard_code} / ${qa.primary_topic} / ${qa.course_stage}`,
boundary: qa.answer_boundary ?? "答复仅基于已审核答疑资产生成,不能替代专业诊断、法律判断或医疗建议。",
createdAt: nowText()
};
}
function EmptyState({ tab }: { tab: MobileTab }) {
const copy = {
history: "登录后这里会展示你的历史提问记录。当前先用本机 mock 会话演示。",
me: "账号、学习阶段、隐私设置后续会接真实接口;现在先预留微信授权入口。",
qa: ""
};
if (tab === "qa") return null;
return (
{tab === "history" ? : }
{copy[tab]}
);
}
export default function H5QAExperience() {
const [activeTab, setActiveTab] = useState("qa");
const [authOpen, setAuthOpen] = useState(false);
const [input, setInput] = useState("");
const [messages, setMessages] = useState(initialMessages);
const [callableQa, setCallableQa] = useState([]);
const [loadingQa, setLoadingQa] = useState(true);
const [user, setUser] = useState(null);
const bottomRef = useRef(null);
const qaSource = useMemo(() => (callableQa.length > 0 ? callableQa : mockCallableQa), [callableQa]);
useEffect(() => {
api
.get("/standard-qa/callable")
.then(setCallableQa)
.catch(() => setCallableQa([]))
.finally(() => setLoadingQa(false));
}, []);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
}, [messages, activeTab]);
function mockLogin(mode: MockUser["mode"]) {
setUser({
mode,
name: mode === "login" ? "大本营学员" : "新学员",
phone: "138****2026"
});
setAuthOpen(false);
}
function ask(question: string) {
const trimmed = question.trim();
if (!trimmed) return;
const matchedQa = findQaAnswer(trimmed, qaSource);
setMessages((current) => [
...current,
{
id: `user-${Date.now()}`,
role: "user",
content: trimmed,
createdAt: nowText()
},
buildAnswerMessage(trimmed, matchedQa)
]);
setInput("");
setActiveTab("qa");
}
function submit(event: FormEvent) {
event.preventDefault();
ask(input);
}
return (
千问千答助手
{loadingQa ? "正在检查可调用库" : callableQa.length > 0 ? "已连接可调用库" : "演示模式"}
{activeTab === "qa" ? (
<>
回答会优先遵守审核边界;涉及医疗、法律、极端风险或个人隐私时,请以人工复核为准。
{messages.map((message) => (
))}
{suggestedQuestions.map((item) => (
))}
>
) : (
)}
setAuthOpen(false)}
onMockLogin={mockLogin}
onLogout={() => {
setUser(null);
setAuthOpen(false);
}}
/>
);
}