Commit 18a982a3 by Liu

feat:提质增效通过提问接口获取欢迎语

parent 5098f0d7
...@@ -60,6 +60,8 @@ export const Chat: React.FC = () => { ...@@ -60,6 +60,8 @@ export const Chat: React.FC = () => {
const fromCollectRef = useRef<boolean>(false) const fromCollectRef = useRef<boolean>(false)
// 记录正在处理的 conversationId,避免重复调用 // 记录正在处理的 conversationId,避免重复调用
const processingConversationIdRef = useRef<string | null>(null) const processingConversationIdRef = useRef<string | null>(null)
// 标记是否为提质增效模式的自动调用(用于提取欢迎语)
const isAutoSubmitQualityImprovementRef = useRef<boolean>(false)
// 当外部系统直接以 /chat/:id 链接进入(没有 location.state,且 URL 中也没有 toolId)时, // 当外部系统直接以 /chat/:id 链接进入(没有 location.state,且 URL 中也没有 toolId)时,
// 视为一次新的会话入口:重置为制度活化,清除历史遗留的工具模式状态 // 视为一次新的会话入口:重置为制度活化,清除历史遗留的工具模式状态
...@@ -143,6 +145,27 @@ export const Chat: React.FC = () => { ...@@ -143,6 +145,27 @@ export const Chat: React.FC = () => {
const lastIndex = newItems.length - 1 const lastIndex = newItems.length - 1
const isEmptyQuestion = !question.trim() const isEmptyQuestion = !question.trim()
// 提质增效模式下,自动调用时第一个数据块作为欢迎语
if (isAutoSubmitQualityImprovementRef.current && isEmptyQuestion && msg.content.data.answer) {
// 判断是否为第一个数据块(只有 system 记录或最后一个记录是 system)
const isFirstChunk = newItems.length === 1 && newItems[0].role === 'system'
if (isFirstChunk) {
// 提取欢迎语并更新到 system 记录
const welcomeText = msg.content.data.answer
const systemIndex = newItems.findIndex(item => item.role === 'system')
if (systemIndex >= 0) {
newItems[systemIndex] = {
...newItems[systemIndex],
welcomeText,
} as ChatRecord
}
// 清除标记,后续数据块不再处理为欢迎语
isAutoSubmitQualityImprovementRef.current = false
return newItems
}
}
// 如果是空问题且最后一项不是AI回答,需要添加AI回答 // 如果是空问题且最后一项不是AI回答,需要添加AI回答
if (isEmptyQuestion && (lastIndex < 0 || newItems[lastIndex].role !== 'ai')) { if (isEmptyQuestion && (lastIndex < 0 || newItems[lastIndex].role !== 'ai')) {
newItems.push({ newItems.push({
...@@ -235,6 +258,10 @@ export const Chat: React.FC = () => { ...@@ -235,6 +258,10 @@ export const Chat: React.FC = () => {
// 优先读取缓存中的 toolId,再回退到传参或 Redux // 优先读取缓存中的 toolId,再回退到传参或 Redux
const sessionToolId = sessionStorage.getItem('currentToolId') ?? undefined const sessionToolId = sessionStorage.getItem('currentToolId') ?? undefined
const resolvedToolId = toolId ?? sessionToolId ?? currentToolId ?? undefined const resolvedToolId = toolId ?? sessionToolId ?? currentToolId ?? undefined
// 判断是否为提质增效模式的自动调用(空问题)
const isEmptyQuestion = !question.trim()
const isQualityImprovement = resolvedToolId === '6712395743241'
isAutoSubmitQualityImprovementRef.current = isEmptyQuestion && isQualityImprovement
// 停止之前的请求 // 停止之前的请求
if (abortControllerRef.current) { if (abortControllerRef.current) {
abortControllerRef.current.abort() abortControllerRef.current.abort()
...@@ -411,6 +438,8 @@ export const Chat: React.FC = () => { ...@@ -411,6 +438,8 @@ export const Chat: React.FC = () => {
) )
.then(() => { .then(() => {
// 流结束时执行(通过 Promise resolve 判断) // 流结束时执行(通过 Promise resolve 判断)
// 清除自动调用标记
isAutoSubmitQualityImprovementRef.current = false
// 设置最后一条 AI 回答的 endAnswerFlag,用于控制打字效果结束 // 设置最后一条 AI 回答的 endAnswerFlag,用于控制打字效果结束
setAllItems((prevItems) => { setAllItems((prevItems) => {
const newItems = [...prevItems] const newItems = [...prevItems]
...@@ -441,6 +470,8 @@ export const Chat: React.FC = () => { ...@@ -441,6 +470,8 @@ export const Chat: React.FC = () => {
.catch((error) => { .catch((error) => {
// 流式请求出错时的处理 // 流式请求出错时的处理
console.error('[Chat] 流式请求失败:', error) console.error('[Chat] 流式请求失败:', error)
// 清除自动调用标记
isAutoSubmitQualityImprovementRef.current = false
// 设置最后一条 AI 回答的 endAnswerFlag,用于停止打字效果 // 设置最后一条 AI 回答的 endAnswerFlag,用于停止打字效果
setAllItems((prevItems) => { setAllItems((prevItems) => {
const newItems = [...prevItems] const newItems = [...prevItems]
...@@ -1009,7 +1040,7 @@ export const Chat: React.FC = () => { ...@@ -1009,7 +1040,7 @@ export const Chat: React.FC = () => {
key={uniqueKey} key={uniqueKey}
style={(shouldHideHistoryItem || shouldHideEmptyQuestionAnswer) ? { visibility: 'hidden', height: 0, overflow: 'hidden', margin: 0, padding: 0 } : undefined} style={(shouldHideHistoryItem || shouldHideEmptyQuestionAnswer) ? { visibility: 'hidden', height: 0, overflow: 'hidden', margin: 0, padding: 0 } : undefined}
> >
{record.role === 'system' && <ChatWelcome toolName={currentToolName} />} {record.role === 'system' && <ChatWelcome toolName={currentToolName} welcomeText={(record as any).welcomeText} />}
{record.role === 'user' && <ChatItemUser record={record} />} {record.role === 'user' && <ChatItemUser record={record} />}
{record.role === 'ai' && ( {record.role === 'ai' && (
<ChatAnswerBox <ChatAnswerBox
......
...@@ -5,13 +5,20 @@ import AIIcon from '@/assets/ai-icon.png' ...@@ -5,13 +5,20 @@ import AIIcon from '@/assets/ai-icon.png'
interface ChatWelcomeProps { interface ChatWelcomeProps {
toolName?: string toolName?: string
welcomeText?: string
} }
export const ChatWelcome: React.FC<ChatWelcomeProps> = ({ toolName: _toolName }) => { export const ChatWelcome: React.FC<ChatWelcomeProps> = ({ toolName: _toolName, welcomeText }) => {
const viteOutputObj = import.meta.env.VITE_OUTPUT_OBJ || 'open' const viteOutputObj = import.meta.env.VITE_OUTPUT_OBJ || 'open'
// 根据不同的 toolName 显示不同的提示语 // 根据不同的 toolName 显示不同的提示语
const getWelcomeText = () => { const getWelcomeText = () => {
// 优先使用从接口返回的欢迎语(提质增效模式自动调用时)
if (welcomeText) {
return welcomeText
}
// 回退到原有的 toolId 判断逻辑
const currentToolId = typeof window !== 'undefined' ? sessionStorage.getItem('currentToolId') : '' const currentToolId = typeof window !== 'undefined' ? sessionStorage.getItem('currentToolId') : ''
if (currentToolId === '6712395743240') { if (currentToolId === '6712395743240') {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment