Add manual AI response generation feature in MessageEnter component. Implement handleManualTriggerAi function to allow users to trigger AI replies on demand. Update weChat store with manualTriggerAi function to manage AI request logic and context retrieval. Enhance UI with a reload button for AI responses in AI modes.

This commit is contained in:
超级老白兔
2025-10-29 16:56:44 +08:00
parent 44a8fbe0c9
commit 0d1d082d9e
2 changed files with 118 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
import { Layout, Input, Button, Modal, message } from "antd";
import { Layout, Input, Button, Modal, message, Tooltip } from "antd";
import {
SendOutlined,
FolderOutlined,
@@ -7,6 +7,7 @@ import {
ExportOutlined,
CloseOutlined,
MessageOutlined,
ReloadOutlined,
} from "@ant-design/icons";
import { ContractData, weChatGroup, ChatRecord } from "@/pages/pc/ckbox/data";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
@@ -19,6 +20,7 @@ import styles from "./MessageEnter.module.scss";
import {
useWeChatStore,
clearAiRequestQueue,
manualTriggerAi,
} from "@/store/module/weChat/weChat";
import { useContactStore } from "@/store/module/weChat/contacts";
const { Footer } = Layout;
@@ -91,6 +93,16 @@ const MessageEnter: React.FC<MessageEnterProps> = ({ contract }) => {
}
};
// 手动触发AI生成
const handleManualTriggerAi = async () => {
const success = await manualTriggerAi();
if (success) {
message.success("AI正在生成回复...");
} else {
message.warning("无法生成AI回复请检查消息记录");
}
};
// 发送消息(支持传入内容参数,避免闭包问题)
const handleSend = async (content?: string) => {
const messageContent = content || inputValue; // 优先使用传入的内容
@@ -371,6 +383,19 @@ const MessageEnter: React.FC<MessageEnterProps> = ({ contract }) => {
}
className={styles.toolbarButton}
/>
{/* AI模式下显示重新生成按钮 */}
{(isAiAssist || isAiTakeover) && (
<Tooltip title="重新生成AI回复">
<Button
className={styles.toolbarButton}
type="text"
icon={<ReloadOutlined />}
onClick={handleManualTriggerAi}
disabled={isLoadingAiChat}
/>
</Tooltip>
)}
</div>
<div className={styles.rightTool}>
<ToContract className={styles.rightToolItem} />

View File

@@ -53,6 +53,98 @@ const generateAiId = (): string => {
return `ai_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
};
/**
* 手动触发AI回复生成
* 用于用户主动请求AI生成回复
*/
export const manualTriggerAi = async () => {
const state = useWeChatStore.getState();
const currentContract = state.currentContract;
if (!currentContract) {
console.warn("⚠️ 没有当前联系人无法触发AI");
return false;
}
// 检查是否为AI模式
const aiType = (currentContract as any).aiType || 0;
if (![1, 2].includes(aiType)) {
console.warn("⚠️ 当前不是AI模式无法触发AI");
return false;
}
// 清除之前的AI请求如果有
if (aiRequestTimer || currentAiGenerationId) {
console.log("🔄 清除之前的AI请求");
clearAiRequestQueue("手动重新生成");
}
// 获取最近的消息作为上下文
const currentMessages = state.currentMessages;
if (currentMessages.length === 0) {
console.warn("⚠️ 没有消息记录无法触发AI");
return false;
}
// 找到最近的对方消息(非自己发送的)
const recentMessages = currentMessages
.filter(msg => !msg.isSend && msg.msgType === 1) // 只要对方发的文字消息
.slice(-5); // 最近5条
if (recentMessages.length === 0) {
console.warn("⚠️ 没有对方的消息无法触发AI");
return false;
}
console.log("🔄 手动触发AI回复生成");
// 显示AI加载状态
state.updateIsLoadingAiChat(true);
// 生成唯一的AI请求ID
const generationId = generateAiId();
currentAiGenerationId = generationId;
console.log(`🆔 AI生成ID: ${generationId}`);
console.log(`📝 使用最近 ${recentMessages.length} 条消息作为上下文`);
try {
// 使用最后一条消息作为主要上下文
const lastMessage = recentMessages[recentMessages.length - 1];
// 手动触发时直接调用 AI 对话接口,不需要先调用 dataProcessing
const messageContent = await aiChat({
friendId: currentContract.id,
wechatAccountId: currentContract.wechatAccountId,
message: lastMessage,
});
// 回复到达前检查:是否已被取消
if (currentAiGenerationId !== generationId) {
console.log(
`❌ AI回复已过期丢弃 (当前ID: ${currentAiGenerationId}, 回复ID: ${generationId})`,
);
return false;
}
// 更新AI回复内容
state.updateQuoteMessageContent(messageContent?.content || "");
state.updateIsLoadingAiChat(false);
console.log(
`✅ 手动AI回复成功 [${generationId}]:`,
messageContent?.content,
);
// 清除当前生成ID
currentAiGenerationId = null;
return true;
} catch (error) {
console.error("❌ 手动AI请求失败:", error);
state.updateIsLoadingAiChat(false);
currentAiGenerationId = null;
return false;
}
};
/**
* 微信聊天状态管理 Store
* 使用 Zustand 管理微信聊天相关的状态和操作
@@ -178,11 +270,6 @@ export const useWeChatStore = create<WeChatState>()(
},
/** 设置当前联系人并加载相关数据 */
setCurrentContact: (contract: ContractData | weChatGroup) => {
console.log(
"setCurrentContact - contract.aiType:",
(contract as any).aiType,
); // 调试:查看 aiType 字段
// 切换联系人时清除AI请求定时器和队列
if (aiRequestTimer) {
console.log("切换联系人清除AI请求定时器和队列");