AIClient-2-API/static/app/event-stream.js
hex2077 80d4e16840 feat: 添加可视化Web UI管理控制台及相关功能模块
新增完整的Web UI管理控制台,包含以下主要功能:
1. 响应式设计的现代化界面
2. 实时监控系统状态和提供商统计
3. 配置管理功能,支持多种模型提供商
4. 文件上传和OAuth凭据管理
5. 路径路由调用示例和curl命令生成
6. 实时日志查看和事件流处理
7. 提供完整的UI文档说明

新增多个前端模块文件,包括导航、事件处理、文件上传等功能组件,并更新package.json添加multer依赖以支持文件上传功能。同时添加详细的UI_README.md文档说明所有功能特性和使用方法。
2025-11-11 18:53:39 +08:00

188 lines
5.3 KiB
JavaScript

// Server-Sent Events处理模块
import { eventSource, setEventSource, elements, addLog, autoScroll } from './constants.js';
/**
* Server-Sent Events初始化
*/
function initEventStream() {
if (eventSource) {
eventSource.close();
}
const newEventSource = new EventSource('/api/events');
setEventSource(newEventSource);
newEventSource.onopen = () => {
updateServerStatus(true);
console.log('EventStream connected');
};
newEventSource.onerror = () => {
updateServerStatus(false);
console.log('EventStream disconnected');
};
newEventSource.addEventListener('log', (event) => {
const data = JSON.parse(event.data);
addLogEntry(data);
});
newEventSource.addEventListener('provider', (event) => {
const data = JSON.parse(event.data);
updateProviderStatus(data);
});
newEventSource.addEventListener('provider_update', (event) => {
const data = JSON.parse(event.data);
handleProviderUpdate(data);
});
newEventSource.addEventListener('config_update', (event) => {
const data = JSON.parse(event.data);
handleConfigUpdate(data);
});
}
/**
* 添加日志条目
* @param {Object} logData - 日志数据
*/
function addLogEntry(logData) {
addLog(logData);
if (!elements.logsContainer) return;
const logEntry = document.createElement('div');
logEntry.className = 'log-entry';
const time = new Date(logData.timestamp).toLocaleTimeString();
const levelClass = `log-level-${logData.level}`;
logEntry.innerHTML = `
<span class="log-time">[${time}]</span>
<span class="${levelClass}">[${logData.level.toUpperCase()}]</span>
<span class="log-message">${escapeHtml(logData.message)}</span>
`;
elements.logsContainer.appendChild(logEntry);
if (autoScroll) {
elements.logsContainer.scrollTop = elements.logsContainer.scrollHeight;
}
}
/**
* 更新服务器状态
* @param {boolean} connected - 连接状态
*/
function updateServerStatus(connected) {
if (!elements.serverStatus) return;
const statusBadge = elements.serverStatus;
const icon = statusBadge.querySelector('i');
const text = statusBadge.querySelector('span') || statusBadge.childNodes[1];
if (connected) {
statusBadge.classList.remove('error');
icon.style.color = 'var(--success-color)';
statusBadge.innerHTML = '<i class="fas fa-circle"></i> 已连接';
} else {
statusBadge.classList.add('error');
icon.style.color = 'var(--danger-color)';
statusBadge.innerHTML = '<i class="fas fa-circle"></i> 连接断开';
}
}
/**
* 更新提供商状态
* @param {Object} data - 提供商数据
*/
function updateProviderStatus(data) {
// 触发重新加载提供商列表
if (typeof loadProviders === 'function') {
loadProviders();
}
}
/**
* 处理供应商更新事件
* @param {Object} data - 更新数据
*/
function handleProviderUpdate(data) {
if (data.action && data.providerType) {
// 如果当前打开的模态框是更新事件的供应商类型,则刷新该模态框
const modal = document.querySelector('.provider-modal');
if (modal && modal.getAttribute('data-provider-type') === data.providerType) {
if (typeof refreshProviderConfig === 'function') {
refreshProviderConfig(data.providerType);
}
} else {
// 否则更新主界面的供应商列表
if (typeof loadProviders === 'function') {
loadProviders();
}
}
}
}
// 导入工具函数
import { escapeHtml } from './utils.js';
// 需要从其他模块导入的函数
let loadProviders;
let refreshProviderConfig;
let loadConfigList;
export function setProviderLoaders(providerLoader, providerRefresher) {
loadProviders = providerLoader;
refreshProviderConfig = providerRefresher;
}
export function setConfigLoaders(configLoader) {
loadConfigList = configLoader;
}
/**
* 处理配置更新事件
* @param {Object} data - 更新数据
*/
function handleConfigUpdate(data) {
console.log('[ConfigUpdate] 收到配置更新事件:', data);
// 根据操作类型进行相应处理
switch (data.action) {
case 'delete':
// 文件删除事件,直接刷新配置文件列表
if (loadConfigList) {
loadConfigList();
console.log('[ConfigUpdate] 配置文件列表已刷新(文件删除)');
}
break;
case 'add':
case 'update':
// 文件添加或更新事件,刷新配置文件列表
if (loadConfigList) {
loadConfigList();
console.log('[ConfigUpdate] 配置文件列表已刷新(文件更新)');
}
break;
default:
// 未知操作类型,也刷新列表以确保同步
if (loadConfigList) {
loadConfigList();
console.log('[ConfigUpdate] 配置文件列表已刷新(默认)');
}
break;
}
}
export {
initEventStream,
addLogEntry,
updateServerStatus,
updateProviderStatus,
handleProviderUpdate
};