Files
QuestionProject/hy_qa_asset_backend/frontend/lib/h5MockQa.ts

107 lines
3.0 KiB
TypeScript

import type { CallableQAItem } from "./types";
export type ChatRole = "assistant" | "user";
export type ChatMessage = {
id: string;
role: ChatRole;
content: string;
source?: string;
boundary?: string;
feedback?: "liked" | "disliked";
createdAt: string;
};
export type ChatSession = {
id: string;
title: string;
preview: string;
messages: ChatMessage[];
updatedAt: string;
questionCount: number;
};
export type SuggestedQuestion = {
id: string;
text: string;
tags: string[];
};
export const suggestedQuestions: SuggestedQuestion[] = [
{
id: "parent-child-emotion",
text: "孩子一写作业就发脾气,我怎么接住他的情绪?",
tags: ["亲子关系", "情绪"]
},
{
id: "self-growth",
text: "我知道要行动,但总是拖延,应该先从哪里开始?",
tags: ["个人成长", "行动力"]
},
{
id: "marriage-talk",
text: "伴侣不愿意沟通,我怎么表达才不容易吵起来?",
tags: ["婚姻关系", "沟通"]
}
];
export const initialMessages: ChatMessage[] = [
{
id: "welcome",
role: "assistant",
content:
"你好,我是千问千答助手。你可以把最近遇到的亲子、关系、情绪或行动问题发给我,我会优先基于已审核的答疑资产给你一个可落地的回应。",
boundary: "当前为 H5 体验版,登录暂用 mock 占位;问答答案只读取后端可调用库。",
createdAt: "09:30"
}
];
export function createEmptySession(): ChatSession {
return {
id: `session-${Date.now()}`,
title: "新的问答",
preview: "还没有开始提问",
messages: initialMessages,
updatedAt: new Date().toISOString(),
questionCount: 0
};
}
export function summarizeSession(sessionId: string, messages: ChatMessage[]): ChatSession {
const userMessages = messages.filter((message) => message.role === "user");
const lastMessage = [...messages].reverse().find((message) => message.role === "assistant" || message.role === "user");
const firstQuestion = userMessages[0]?.content;
return {
id: sessionId,
title: firstQuestion ? firstQuestion.slice(0, 24) : "新的问答",
preview: lastMessage?.content.slice(0, 42) ?? "还没有开始提问",
messages,
updatedAt: new Date().toISOString(),
questionCount: userMessages.length
};
}
function scoreQuestion(question: string, qa: CallableQAItem): number {
const haystack = [
qa.standard_question,
qa.standard_answer,
qa.primary_topic,
qa.course_stage,
...qa.problem_tags,
...qa.similar_questions
].join(" ");
return Array.from(new Set(question.trim().split(""))).reduce((score, char) => {
if (!char.trim()) return score;
return haystack.includes(char) ? score + 1 : score;
}, 0);
}
export function findQaAnswer(question: string, qaItems: CallableQAItem[]) {
if (qaItems.length === 0) {
return null;
}
const [best] = [...qaItems].sort((left, right) => scoreQuestion(question, right) - scoreQuestion(question, left));
return best ?? null;
}