daShangDao_psiWebApp/move/demo/ServiceManager.js
2026-06-03 10:53:47 +08:00

338 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* ServiceManager - 服务管理类
* 支持:设置路径、连接、状态查询、启动、停止
* DEBUG模式开启后在浏览器控制台输出详细调试信息
*/
export class ServiceManager {
constructor(baseUrl) {
// 实例属性
this.baseUrl = 'http://127.0.0.1:5000';
this.logs = [];
this.maxLogs = 200;
this.pollInterval = 3000;
this.pollTimer = null;
this.onStatusChange = null;
this.previousStatus = new Map();
this.connected = false;
if (baseUrl) {
this.baseUrl = baseUrl;
}
this.log('info', `ServiceManager 创建 | API: ${this.baseUrl} | DEBUG: ${ServiceManager.DEBUG}`);
}
// ============================================
// DEBUG 控制
// ============================================
/**
* 开启DEBUG模式 - 在浏览器控制台输出详细信息
*/
static enableDebug() {
ServiceManager.DEBUG = true;
console.log('%c[DEBUG]%c 全局DEBUG模式已开启', 'background:#9b59b6;color:#fff;padding:2px 6px;border-radius:3px', 'color:#9b59b6');
}
/**
* 关闭DEBUG模式
*/
static disableDebug() {
ServiceManager.DEBUG = false;
console.log('%c[DEBUG]%c 全局DEBUG模式已关闭', 'background:#9b59b6;color:#fff;padding:2px 6px;border-radius:3px', 'color:#9b59b6');
}
/**
* 获取当前DEBUG状态
*/
static isDebugEnabled() {
return ServiceManager.DEBUG;
}
// ============================================
// 内部日志
// ============================================
log(level, message, data) {
const entry = {
time: new Date().toLocaleTimeString(),
level,
message,
data
};
this.logs.push(entry);
if (this.logs.length > this.maxLogs) {
this.logs.shift();
}
// 控制台输出DEBUG模式下更详细
const timestamp = new Date().toLocaleTimeString();
const prefix = `[${level.toUpperCase()}]`;
if (ServiceManager.DEBUG) {
const style = this.getConsoleStyle(level);
console.log(`%c${timestamp}%c ${prefix}%c ${message}`, 'color:#888', style, 'color:inherit', data || '');
if (data !== undefined) {
console.log(`%c${timestamp}%c [DATA]`, 'color:#888', 'color:#3498db', data);
}
}
else if (level === 'error' || level === 'warn') {
const style = this.getConsoleStyle(level);
console.log(`%c${prefix}%c ${message}`, style, 'color:inherit');
}
return entry;
}
getConsoleStyle(level) {
switch (level) {
case 'error': return 'background:#e74c3c;color:#fff;padding:2px 6px;border-radius:3px';
case 'warn': return 'background:#f39c12;color:#fff;padding:2px 6px;border-radius:3px';
case 'success': return 'background:#27ae60;color:#fff;padding:2px 6px;border-radius:3px';
case 'info': return 'background:#3498db;color:#fff;padding:2px 6px;border-radius:3px';
case 'debug': return 'background:#9b59b6;color:#fff;padding:2px 6px;border-radius:3px';
default: return 'background:#95a5a6;color:#fff;padding:2px 6px;border-radius:3px';
}
}
// ============================================
// 配置方法
// ============================================
/**
* 设置API地址
* @param url API服务器地址如 http://127.0.0.1:5000
*/
setBaseUrl(url) {
this.log('info', `API地址设置: ${this.baseUrl}${url}`);
this.baseUrl = url;
}
/**
* 获取当前API地址
*/
getBaseUrl() {
return this.baseUrl;
}
/**
* 设置轮询间隔(毫秒)
* @param ms 间隔时间默认3000ms
*/
setPollInterval(ms) {
this.log('info', `轮询间隔设置: ${this.pollInterval}ms → ${ms}ms`);
this.pollInterval = ms;
if (this.pollTimer) {
this.stopAutoRefresh();
this.startAutoRefresh();
}
}
/**
* 获取轮询间隔
*/
getPollInterval() {
return this.pollInterval;
}
// ============================================
// 状态查询
// ============================================
/**
* 获取连接状态
*/
isConnected() {
return this.connected;
}
/**
* 获取所有服务状态
*/
async getServicesStatus() {
this.log('debug', `GET /api/services`);
try {
const response = await fetch(`${this.baseUrl}/api/services`);
this.log('debug', `响应状态: ${response.status} ${response.statusText}`);
if (!response.ok) {
this.log('error', `HTTP错误: ${response.status}`);
this.connected = false;
return [];
}
const result = await response.json();
this.log('debug', `响应数据: ${JSON.stringify(result)}`);
if (result.code === 0 && result.data) {
this.connected = true;
// 检查状态变化
for (const service of result.data) {
const prev = this.previousStatus.get(service.id);
if (prev !== undefined && prev !== service.running) {
this.log('warn', `状态变化: ${service.name}${service.running ? '运行中' : '已停止'}`, { id: service.id, from: prev, to: service.running });
if (this.onStatusChange) {
this.onStatusChange(service);
}
}
this.previousStatus.set(service.id, service.running);
}
this.log('success', `获取服务状态成功: ${result.data.length} 个服务`);
return result.data;
}
this.log('error', `API返回错误: ${result.msg || '未知错误'}`);
return [];
}
catch (error) {
this.log('error', `请求失败: ${error.message}`, { error: error.toString(), stack: error.stack });
this.connected = false;
return [];
}
}
/**
* 获取单个服务状态
* @param id 服务ID
*/
async getServiceStatus(id) {
this.log('debug', `GET /api/services/${id}`);
try {
const response = await fetch(`${this.baseUrl}/api/services/${id}`);
this.log('debug', `响应状态: ${response.status}`);
if (!response.ok) {
this.log('error', `HTTP错误: ${response.status}`);
return null;
}
const result = await response.json();
this.log('debug', `响应数据: ${JSON.stringify(result)}`);
if (result.code === 0 && result.data) {
this.log('success', `获取服务 ${id} 状态成功`, result.data);
return result.data;
}
this.log('error', `获取失败: ${result.msg}`);
return null;
}
catch (error) {
this.log('error', `请求失败: ${error.message}`);
return null;
}
}
// ============================================
// 服务控制
// ============================================
/**
* 启动服务
* @param id 服务ID
*/
async startService(id) {
this.log('info', `启动服务: ${id}`);
this.log('debug', `POST /api/services/${id}/start`);
try {
const response = await fetch(`${this.baseUrl}/api/services/${id}/start`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
this.log('debug', `响应状态: ${response.status}`);
const result = await response.json();
this.log('debug', `响应数据: ${JSON.stringify(result)}`);
if (result.code === 0) {
this.log('success', `启动成功: ${result.msg}`, { pid: result.pid });
return true;
}
this.log('error', `启动失败: ${result.msg}`);
return false;
}
catch (error) {
this.log('error', `启动请求失败: ${error.message}`);
return false;
}
}
/**
* 停止服务
* @param id 服务ID
*/
async stopService(id) {
this.log('info', `停止服务: ${id}`);
this.log('debug', `POST /api/services/${id}/stop`);
try {
const response = await fetch(`${this.baseUrl}/api/services/${id}/stop`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
this.log('debug', `响应状态: ${response.status}`);
const result = await response.json();
this.log('debug', `响应数据: ${JSON.stringify(result)}`);
if (result.code === 0) {
this.log('success', `停止成功: ${result.msg}`, { killed: result.killed });
return true;
}
this.log('error', `停止失败: ${result.msg}`);
return false;
}
catch (error) {
this.log('error', `停止请求失败: ${error.message}`);
return false;
}
}
// ============================================
// 自动刷新
// ============================================
/**
* 启动自动刷新
* @param callback 每次刷新后的回调函数
*/
startAutoRefresh(callback) {
if (this.pollTimer) {
this.log('warn', '自动刷新已在运行中');
return;
}
this.log('info', `启动自动刷新,间隔: ${this.pollInterval}ms`);
const doRefresh = async () => {
this.log('debug', '--- 自动刷新触发 ---');
const services = await this.getServicesStatus();
if (callback) {
callback(services);
}
};
doRefresh();
this.pollTimer = setInterval(doRefresh, this.pollInterval);
this.log('success', '自动刷新已开始');
}
/**
* 停止自动刷新
*/
stopAutoRefresh() {
if (this.pollTimer) {
clearInterval(this.pollTimer);
this.pollTimer = null;
this.log('info', '自动刷新已停止');
}
else {
this.log('warn', '自动刷新未在运行');
}
}
/**
* 检查自动刷新是否运行中
*/
isAutoRefreshRunning() {
return this.pollTimer !== null;
}
// ============================================
// 状态变化回调
// ============================================
/**
* 设置状态变化回调
* @param callback 服务状态变化时调用
*/
setOnStatusChange(callback) {
this.onStatusChange = callback;
this.log('info', '状态变化回调已设置');
}
// ============================================
// 日志管理
// ============================================
/**
* 获取所有日志
*/
getLogs() {
return [...this.logs];
}
/**
* 清空日志
*/
clearLogs() {
this.logs = [];
this.log('info', '日志已清空');
}
// ============================================
// 销毁
// ============================================
/**
* 销毁实例,停止所有定时器
*/
destroy() {
this.log('info', '销毁 ServiceManager 实例');
this.stopAutoRefresh();
this.logs = [];
this.connected = false;
}
}
// 调试开关
ServiceManager.DEBUG = false;