199 lines
5.5 KiB
JavaScript
199 lines
5.5 KiB
JavaScript
// AI 厂商后台事件代理,集中管理全局开关、厂商状态、默认厂商和连通性测试。
|
|
|
|
let adminAiProvidersControlsBound = false;
|
|
|
|
/**
|
|
* 读取 CSRF 令牌,供后台 AJAX 请求使用。
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
function getCsrfToken() {
|
|
return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") ?? "";
|
|
}
|
|
|
|
/**
|
|
* 使用后台接口切换状态类请求。
|
|
*
|
|
* @param {string} url
|
|
* @returns {Promise<object>}
|
|
*/
|
|
async function postJson(url) {
|
|
const response = await fetch(url, {
|
|
method: "POST",
|
|
headers: {
|
|
"X-CSRF-TOKEN": getCsrfToken(),
|
|
Accept: "application/json",
|
|
},
|
|
});
|
|
|
|
return response.json();
|
|
}
|
|
|
|
/**
|
|
* 同步聊天机器人总开关按钮与状态文案。
|
|
*
|
|
* @param {HTMLButtonElement} button
|
|
* @param {boolean} enabled
|
|
* @returns {void}
|
|
*/
|
|
function renderChatBotState(button, enabled) {
|
|
const knob = button.firstElementChild;
|
|
const statusText = document.getElementById("chatbot-status-text");
|
|
|
|
button.classList.toggle("bg-emerald-500", enabled);
|
|
button.classList.toggle("bg-gray-300", !enabled);
|
|
knob?.classList.toggle("translate-x-6", enabled);
|
|
knob?.classList.toggle("translate-x-1", !enabled);
|
|
|
|
if (statusText) {
|
|
statusText.textContent = enabled ? "已开启" : "已关闭";
|
|
statusText.classList.toggle("text-emerald-600", enabled);
|
|
statusText.classList.toggle("text-gray-400", !enabled);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 切换全局聊天机器人开关。
|
|
*
|
|
* @param {HTMLButtonElement} button
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async function toggleChatBot(button) {
|
|
try {
|
|
const toggleUrl = button.getAttribute("data-ai-chatbot-toggle-url");
|
|
if (!toggleUrl) {
|
|
return;
|
|
}
|
|
|
|
const data = await postJson(toggleUrl);
|
|
if (data.status === "success") {
|
|
renderChatBotState(button, Boolean(data.enabled));
|
|
window.alert(data.message);
|
|
}
|
|
} catch (error) {
|
|
window.alert(`操作失败:${error.message}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 切换厂商启用状态,成功后刷新列表。
|
|
*
|
|
* @param {HTMLButtonElement} button
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async function toggleProvider(button) {
|
|
try {
|
|
const toggleUrl = button.getAttribute("data-ai-provider-toggle-url");
|
|
if (!toggleUrl) {
|
|
return;
|
|
}
|
|
|
|
const data = await postJson(toggleUrl);
|
|
if (data.status === "success") {
|
|
window.location.reload();
|
|
}
|
|
} catch (error) {
|
|
window.alert(`操作失败:${error.message}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 将当前厂商设为默认,成功后刷新列表。
|
|
*
|
|
* @param {HTMLButtonElement} button
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async function setDefaultProvider(button) {
|
|
try {
|
|
const defaultUrl = button.getAttribute("data-ai-provider-default-url");
|
|
if (!defaultUrl) {
|
|
return;
|
|
}
|
|
|
|
const data = await postJson(defaultUrl);
|
|
if (data.status === "success") {
|
|
window.location.reload();
|
|
}
|
|
} catch (error) {
|
|
window.alert(`操作失败:${error.message}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 测试 AI 厂商接口连通性,并恢复按钮状态。
|
|
*
|
|
* @param {HTMLButtonElement} button
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async function testProviderConnection(button) {
|
|
const testUrl = button.getAttribute("data-ai-provider-test-url");
|
|
const providerName = button.getAttribute("data-ai-provider-name") ?? "AI 厂商";
|
|
if (!testUrl) {
|
|
return;
|
|
}
|
|
|
|
const originalText = button.textContent;
|
|
button.textContent = "测试中…";
|
|
button.disabled = true;
|
|
|
|
try {
|
|
const data = await postJson(testUrl);
|
|
if (data.ok) {
|
|
window.alert(`✅ 「${providerName}」 连通成功!\n⤵ 响应耗时:${data.ms}ms(包含冷启动)\n🤖 模型回复:${data.message}`);
|
|
} else {
|
|
window.alert(`❌ 「${providerName}」 连通失败!\n耗时:${data.ms}ms\n错误:${data.message}`);
|
|
}
|
|
} catch (error) {
|
|
window.alert(`请求异常:${error.message}`);
|
|
} finally {
|
|
button.textContent = originalText;
|
|
button.disabled = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 绑定 AI 厂商后台页操作。
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
export function bindAdminAiProvidersControls() {
|
|
if (adminAiProvidersControlsBound || typeof document === "undefined") {
|
|
return;
|
|
}
|
|
|
|
adminAiProvidersControlsBound = true;
|
|
|
|
document.addEventListener("click", (event) => {
|
|
if (!(event.target instanceof Element)) {
|
|
return;
|
|
}
|
|
|
|
const chatBotToggle = event.target.closest("[data-ai-chatbot-toggle-url]");
|
|
if (chatBotToggle instanceof HTMLButtonElement) {
|
|
event.preventDefault();
|
|
void toggleChatBot(chatBotToggle);
|
|
return;
|
|
}
|
|
|
|
const providerToggle = event.target.closest("[data-ai-provider-toggle-url]");
|
|
if (providerToggle instanceof HTMLButtonElement) {
|
|
event.preventDefault();
|
|
void toggleProvider(providerToggle);
|
|
return;
|
|
}
|
|
|
|
const defaultButton = event.target.closest("[data-ai-provider-default-url]");
|
|
if (defaultButton instanceof HTMLButtonElement) {
|
|
event.preventDefault();
|
|
void setDefaultProvider(defaultButton);
|
|
return;
|
|
}
|
|
|
|
const testButton = event.target.closest("[data-ai-provider-test-url]");
|
|
if (testButton instanceof HTMLButtonElement) {
|
|
event.preventDefault();
|
|
void testProviderConnection(testButton);
|
|
}
|
|
});
|
|
}
|