Use backend callable QA for H5 answers

This commit is contained in:
2026-07-05 18:53:46 +08:00
parent cd73ed3001
commit a4b59add07
2 changed files with 49 additions and 64 deletions

View File

@@ -20,7 +20,6 @@ import {
createEmptySession,
findQaAnswer,
initialMessages,
mockCallableQa,
suggestedQuestions,
summarizeSession,
type ChatSession,
@@ -51,6 +50,22 @@ function buildAnswerMessage(question: string, qa: CallableQAItem): ChatMessage {
};
}
function buildUnavailableMessage(reason: "loading" | "empty" | "error"): ChatMessage {
const content = {
loading: "我还在连接可调用问答库,请稍等几秒后再试。",
empty: "当前可调用问答库还没有可用内容。请先到后台标准问答库中,把已审核、低/中风险、已脱敏或无需脱敏的问答标记为“可调用”。",
error: "暂时连接不到后端可调用库,请检查后端服务或网络连接后再试。"
}[reason];
return {
id: `assistant-unavailable-${Date.now()}`,
role: "assistant",
content,
boundary: "H5 端不会使用未审核或不可调用的内容生成回答。",
createdAt: nowText()
};
}
function formatSessionTime(value: string) {
return new Intl.DateTimeFormat("zh-CN", {
month: "2-digit",
@@ -70,11 +85,12 @@ export default function H5QAExperience() {
const [currentSessionId, setCurrentSessionId] = useState("");
const [callableQa, setCallableQa] = useState<CallableQAItem[]>([]);
const [loadingQa, setLoadingQa] = useState(true);
const [qaLoadError, setQaLoadError] = useState<string | null>(null);
const [user, setUser] = useState<MockUser | null>(null);
const [copiedMessageId, setCopiedMessageId] = useState<string | null>(null);
const bottomRef = useRef<HTMLDivElement | null>(null);
const qaSource = useMemo(() => (callableQa.length > 0 ? callableQa : mockCallableQa), [callableQa]);
const qaStatusText = loadingQa ? "正在连接可调用库" : qaLoadError ? "后端连接异常" : callableQa.length > 0 ? "已连接可调用库" : "可调用库为空";
useEffect(() => {
const fallback = createEmptySession();
@@ -101,8 +117,14 @@ export default function H5QAExperience() {
useEffect(() => {
api
.get<CallableQAItem[]>("/standard-qa/callable")
.then(setCallableQa)
.catch(() => setCallableQa([]))
.then((items) => {
setCallableQa(items);
setQaLoadError(null);
})
.catch((error) => {
setCallableQa([]);
setQaLoadError(error instanceof Error ? error.message : "可调用库接口请求失败");
})
.finally(() => setLoadingQa(false));
}, []);
@@ -173,8 +195,15 @@ export default function H5QAExperience() {
const trimmed = question.trim();
if (!trimmed) return;
const matchedQa = findQaAnswer(trimmed, qaSource);
const matchedQa = findQaAnswer(trimmed, callableQa);
const timestamp = Date.now();
const assistantMessage = loadingQa
? buildUnavailableMessage("loading")
: qaLoadError
? buildUnavailableMessage("error")
: matchedQa
? { ...buildAnswerMessage(trimmed, matchedQa), id: `assistant-${timestamp}` }
: buildUnavailableMessage("empty");
const nextMessages: ChatMessage[] = [
...messages,
{
@@ -183,7 +212,7 @@ export default function H5QAExperience() {
content: trimmed,
createdAt: nowText()
},
{ ...buildAnswerMessage(trimmed, matchedQa), id: `assistant-${timestamp}` }
assistantMessage
];
persistMessages(nextMessages);
setInput("");
@@ -207,7 +236,7 @@ export default function H5QAExperience() {
</div>
</div>
<div className="space-y-3 text-sm leading-6 text-slate-600">
<p> mock 使</p>
<p> mock </p>
<p></p>
</div>
</div>
@@ -224,7 +253,7 @@ export default function H5QAExperience() {
<h1 className="text-lg font-semibold leading-6"></h1>
<div className="mt-0.5 flex items-center gap-1 text-xs text-slate-500">
<ShieldCheck className="h-3.5 w-3.5 text-jade" aria-hidden />
{loadingQa ? "正在检查可调用库" : callableQa.length > 0 ? "已连接可调用库" : "演示模式"}
{qaStatusText}
</div>
</div>
</div>
@@ -254,6 +283,11 @@ export default function H5QAExperience() {
<div className="mb-4 rounded-md border border-teal-100 bg-teal-50 px-3 py-2 text-xs leading-5 text-teal-800">
</div>
{!loadingQa && (qaLoadError || callableQa.length === 0) ? (
<div className="mb-4 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs leading-5 text-amber-800">
{qaLoadError ? `可调用库接口异常:${qaLoadError}` : "当前后端可调用库为空H5 不会用本地 mock 内容代替真实答案。"}
</div>
) : null}
<div className="space-y-4">
{messages.map((message) => (
<ChatBubble key={message.id} message={message} onCopy={copyMessage} onFeedback={setFeedback} />
@@ -359,7 +393,7 @@ export default function H5QAExperience() {
</div>
<div className="flex items-center justify-between">
<span></span>
<span className="font-medium text-ink">{callableQa.length > 0 ? "接口数据" : "mock 演示"}</span>
<span className="font-medium text-ink">{qaLoadError ? "接口异常" : callableQa.length > 0 ? "接口数据" : "等待入库"}</span>
</div>
</section>
<button