135 lines
3.5 KiB
JavaScript
135 lines
3.5 KiB
JavaScript
// 聊天室 AI 小班长交互模块,提供 sendToChatBot/clearChatBotContext 兼容入口。
|
|
|
|
import { escapeHtml } from "./html.js";
|
|
|
|
let chatBotSending = false;
|
|
|
|
/**
|
|
* 读取页面 CSRF Token。
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
function getCsrfToken() {
|
|
return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") || "";
|
|
}
|
|
|
|
/**
|
|
* 判断包厢窗口是否需要自动滚动到底部。
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
function shouldAutoScroll() {
|
|
return window.isChatAutoScrollEnabled?.() ?? true;
|
|
}
|
|
|
|
/**
|
|
* 将系统提示追加到包厢窗口。
|
|
*
|
|
* @param {string} html
|
|
* @returns {void}
|
|
*/
|
|
function appendPrivateSystemLine(html) {
|
|
const messageBox = document.getElementById("chat-messages-container2");
|
|
if (!messageBox) {
|
|
return;
|
|
}
|
|
|
|
const line = document.createElement("div");
|
|
line.className = "msg-line";
|
|
line.innerHTML = html;
|
|
messageBox.appendChild(line);
|
|
|
|
if (shouldAutoScroll()) {
|
|
messageBox.scrollTop = messageBox.scrollHeight;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 将 AI 错误提示追加到包厢窗口。
|
|
*
|
|
* @param {string} text
|
|
* @returns {void}
|
|
*/
|
|
function appendBotError(text) {
|
|
appendPrivateSystemLine(`<span style="color: #dc2626;">🤖【AI小班长】${escapeHtml(text)}</span>`);
|
|
}
|
|
|
|
/**
|
|
* 发送消息给 AI 机器人。
|
|
*
|
|
* @param {string} content
|
|
* @param {boolean} [isSecret]
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export async function sendToChatBot(content, isSecret = false) {
|
|
if (chatBotSending) {
|
|
window.chatDialog?.alert?.("AI 正在思考中,请稍候...", "提示", "#336699");
|
|
return;
|
|
}
|
|
|
|
chatBotSending = true;
|
|
|
|
try {
|
|
const response = await fetch(window.chatContext.chatBotUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
"X-CSRF-TOKEN": getCsrfToken(),
|
|
"Content-Type": "application/json",
|
|
"Accept": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
message: content,
|
|
room_id: window.chatContext.roomId,
|
|
is_secret: isSecret ? 1 : 0,
|
|
}),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok || data.status !== "success") {
|
|
// AI 接口错误只写入包厢窗口,避免失败提示刷到公屏。
|
|
appendBotError(data.message || "回复失败,请稍后重试");
|
|
}
|
|
} catch (error) {
|
|
appendBotError("网络连接错误,请稍后重试");
|
|
} finally {
|
|
chatBotSending = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 清除与 AI 小助手的对话上下文。
|
|
*
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export async function clearChatBotContext() {
|
|
try {
|
|
const response = await fetch(window.chatContext.chatBotClearUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
"X-CSRF-TOKEN": getCsrfToken(),
|
|
"Accept": "application/json",
|
|
},
|
|
});
|
|
const data = await response.json();
|
|
|
|
appendPrivateSystemLine(`<span style="color: #16a34a;">🤖【系统】${escapeHtml(data.message || "对话已重置")}</span>`);
|
|
} catch (error) {
|
|
window.chatDialog?.alert?.(`清除失败:${error.message}`, "操作失败", "#cc4444");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 暴露 AI 小班长操作给存量发送消息逻辑。
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
export function bindChatBotControls() {
|
|
if (typeof window === "undefined") {
|
|
return;
|
|
}
|
|
|
|
window.sendToChatBot = sendToChatBot;
|
|
window.clearChatBotContext = clearChatBotContext;
|
|
}
|