BUG修复:添加分离式刷新按钮
This commit is contained in:
parent
ec5c2db848
commit
00617621f9
@ -195,13 +195,18 @@ function getAliyunRegions($configId) {
|
||||
*/
|
||||
function getAliyunSwasRegions($configId) {
|
||||
return [
|
||||
'cn-hangzhou', // 华东1(杭州)
|
||||
'cn-shanghai', // 华东2(上海)
|
||||
'cn-qingdao', // 华北1(青岛)
|
||||
'cn-beijing', // 华北2(北京)
|
||||
'cn-zhangjiakou', // 华北3(张家口)
|
||||
'cn-huhehaote', // 华北5(呼和浩特)
|
||||
'cn-wulanchabu', // 华北6(乌兰察布)
|
||||
'cn-hangzhou', // 华东1(杭州)
|
||||
'cn-shanghai', // 华东2(上海)
|
||||
'cn-nanjing', // 华东5(南京)
|
||||
'cn-fuzhou', // 华东6(福州)
|
||||
'cn-shenzhen', // 华南1(深圳)
|
||||
'cn-heyuan', // 华南2(河源)
|
||||
'cn-guangzhou', // 华南3(广州)
|
||||
'cn-chengdu', // 西南1(成都)
|
||||
'cn-hongkong', // 中国香港
|
||||
'ap-southeast-1', // 新加坡
|
||||
|
||||
@ -141,10 +141,61 @@ function initVpsTables($db) {
|
||||
api_key TEXT NOT NULL,
|
||||
auto_monitor BOOLEAN DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(site_url, account)
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
");
|
||||
|
||||
// 迁移:如果存在旧的UNIQUE约束,需要重建表
|
||||
migrateConfigsTable($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移configs表,删除UNIQUE(site_url, account)约束
|
||||
* 允许同一个源添加多个不同的AccessKey
|
||||
*/
|
||||
function migrateConfigsTable($db) {
|
||||
try {
|
||||
// 检查是否存在旧的唯一约束
|
||||
$result = $db->query("PRAGMA index_list(configs)");
|
||||
$hasOldConstraint = false;
|
||||
|
||||
foreach ($result as $index) {
|
||||
if (isset($index['name']) && strpos($index['name'], 'site_url') !== false) {
|
||||
$hasOldConstraint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasOldConstraint) {
|
||||
// 需要迁移:创建新表 -> 复制数据 -> 删除旧表 -> 重命名
|
||||
$db->execute("ALTER TABLE configs RENAME TO configs_old");
|
||||
|
||||
$db->execute("
|
||||
CREATE TABLE configs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
api_label TEXT NOT NULL UNIQUE,
|
||||
site_type TEXT NOT NULL,
|
||||
site_url TEXT,
|
||||
account TEXT NOT NULL,
|
||||
api_key TEXT NOT NULL,
|
||||
auto_monitor BOOLEAN DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
");
|
||||
|
||||
$db->execute("
|
||||
INSERT INTO configs (id, api_label, site_type, site_url, account, api_key, auto_monitor, created_at, updated_at)
|
||||
SELECT id, api_label, site_type, site_url, account, api_key, auto_monitor, created_at, updated_at
|
||||
FROM configs_old
|
||||
");
|
||||
|
||||
$db->execute("DROP TABLE configs_old");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// 迁移失败不影响正常使用,记录日志即可
|
||||
error_log("[迁移警告] configs表迁移失败: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -12,7 +12,8 @@ class DatabaseManager:
|
||||
|
||||
def __init__(self, db_dir=None):
|
||||
if db_dir is None:
|
||||
db_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'db')
|
||||
db_dir = os.path.join(os.path.dirname(
|
||||
os.path.abspath(__file__)), 'db')
|
||||
|
||||
self.db_dir = db_dir
|
||||
os.makedirs(db_dir, exist_ok=True)
|
||||
@ -46,8 +47,7 @@ class DatabaseManager:
|
||||
api_key TEXT NOT NULL,
|
||||
auto_monitor BOOLEAN DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(site_url, account)
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''')
|
||||
|
||||
@ -81,9 +81,12 @@ class DatabaseManager:
|
||||
)
|
||||
''')
|
||||
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_vps_config ON vps_list(config_id)')
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_vps_vps_id ON vps_list(vps_id)')
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_vps_unique ON vps_list(vps_id, ip_address)')
|
||||
cursor.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_vps_config ON vps_list(config_id)')
|
||||
cursor.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_vps_vps_id ON vps_list(vps_id)')
|
||||
cursor.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_vps_unique ON vps_list(vps_id, ip_address)')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
@ -121,10 +124,14 @@ class DatabaseManager:
|
||||
)
|
||||
''')
|
||||
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_ping_vps ON ping_status(vps_id)')
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_ping_time ON ping_status(check_time)')
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_summary_vps ON vps_summary(vps_id)')
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_summary_date ON vps_summary(date)')
|
||||
cursor.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_ping_vps ON ping_status(vps_id)')
|
||||
cursor.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_ping_time ON ping_status(check_time)')
|
||||
cursor.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_summary_vps ON vps_summary(vps_id)')
|
||||
cursor.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_summary_date ON vps_summary(date)')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
@ -193,7 +200,8 @@ class DatabaseManager:
|
||||
values = list(kwargs.values())
|
||||
values.append(config_id)
|
||||
|
||||
cursor.execute(f'UPDATE configs SET {fields}, updated_at = CURRENT_TIMESTAMP WHERE id = ?', values)
|
||||
cursor.execute(
|
||||
f'UPDATE configs SET {fields}, updated_at = CURRENT_TIMESTAMP WHERE id = ?', values)
|
||||
|
||||
affected = cursor.rowcount
|
||||
conn.commit()
|
||||
@ -380,7 +388,8 @@ class DatabaseManager:
|
||||
conn = self.get_connection(self.vpslist_db)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT * FROM vps_list WHERE config_id = ? ORDER BY vps_id', (config_id,))
|
||||
cursor.execute(
|
||||
'SELECT * FROM vps_list WHERE config_id = ? ORDER BY vps_id', (config_id,))
|
||||
vps_list = [dict(row) for row in cursor.fetchall()]
|
||||
|
||||
conn.close()
|
||||
@ -398,7 +407,8 @@ class DatabaseManager:
|
||||
values = list(kwargs.values())
|
||||
values.append(vps_id)
|
||||
|
||||
cursor.execute(f'UPDATE vps_list SET {fields}, last_check = CURRENT_TIMESTAMP WHERE vps_id = ?', values)
|
||||
cursor.execute(
|
||||
f'UPDATE vps_list SET {fields}, last_check = CURRENT_TIMESTAMP WHERE vps_id = ?', values)
|
||||
|
||||
affected = cursor.rowcount
|
||||
conn.commit()
|
||||
@ -415,7 +425,8 @@ class DatabaseManager:
|
||||
conn = self.get_connection(self.vpslist_db)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT * FROM vps_list WHERE section = 1 ORDER BY config_id, vps_id')
|
||||
cursor.execute(
|
||||
'SELECT * FROM vps_list WHERE section = 1 ORDER BY config_id, vps_id')
|
||||
vps_list = [dict(row) for row in cursor.fetchall()]
|
||||
|
||||
conn.close()
|
||||
@ -517,8 +528,10 @@ class DatabaseManager:
|
||||
conn = self.get_connection(self.status_db)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cutoff_date = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d %H:%M:%S')
|
||||
cursor.execute('DELETE FROM ping_status WHERE check_time < ?', (cutoff_date,))
|
||||
cutoff_date = (datetime.now() - timedelta(days=days)
|
||||
).strftime('%Y-%m-%d %H:%M:%S')
|
||||
cursor.execute(
|
||||
'DELETE FROM ping_status WHERE check_time < ?', (cutoff_date,))
|
||||
|
||||
deleted = cursor.rowcount
|
||||
conn.commit()
|
||||
@ -527,8 +540,8 @@ class DatabaseManager:
|
||||
return deleted
|
||||
|
||||
def save_vps_summary(self, vps_id, date, avg_latency, max_latency, min_latency,
|
||||
count_under_100, count_100_to_300, count_300_to_500,
|
||||
count_abnormal, availability):
|
||||
count_under_100, count_100_to_300, count_300_to_500,
|
||||
count_abnormal, availability):
|
||||
"""保存VPS摘要统计"""
|
||||
conn = self.get_connection(self.status_db)
|
||||
cursor = conn.cursor()
|
||||
@ -551,9 +564,11 @@ class DatabaseManager:
|
||||
cursor = conn.cursor()
|
||||
|
||||
if date:
|
||||
cursor.execute('SELECT * FROM vps_summary WHERE vps_id = ? AND date = ?', (vps_id, date))
|
||||
cursor.execute(
|
||||
'SELECT * FROM vps_summary WHERE vps_id = ? AND date = ?', (vps_id, date))
|
||||
else:
|
||||
cursor.execute('SELECT * FROM vps_summary WHERE vps_id = ? ORDER BY date DESC LIMIT 1', (vps_id,))
|
||||
cursor.execute(
|
||||
'SELECT * FROM vps_summary WHERE vps_id = ? ORDER BY date DESC LIMIT 1', (vps_id,))
|
||||
|
||||
row = cursor.fetchone()
|
||||
conn.close()
|
||||
@ -566,7 +581,8 @@ class DatabaseManager:
|
||||
cursor = conn.cursor()
|
||||
|
||||
if date:
|
||||
cursor.execute('SELECT * FROM vps_summary WHERE date = ? ORDER BY vps_id', (date,))
|
||||
cursor.execute(
|
||||
'SELECT * FROM vps_summary WHERE date = ? ORDER BY vps_id', (date,))
|
||||
else:
|
||||
cursor.execute('''
|
||||
SELECT vs.* FROM vps_summary vs
|
||||
|
||||
86
index.php
86
index.php
@ -87,8 +87,52 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$errorMsg = $result['error'] ?? $result['msg'] ?? '未知错误';
|
||||
$message = '<div class="error-message"><h3>❌ 操作失败</h3><p>' . htmlspecialchars($errorMsg) . '</p></div>';
|
||||
}
|
||||
} elseif ($action === 'refresh_single_config') {
|
||||
// 单独刷新某个配置
|
||||
$configId = intval($_POST['config_id'] ?? 0);
|
||||
|
||||
if ($configId > 0) {
|
||||
$configDb = getVpsDB();
|
||||
$config = $configDb->queryOne('SELECT * FROM configs WHERE id = ?', [$configId]);
|
||||
|
||||
if ($config) {
|
||||
$success = false;
|
||||
$typeName = '';
|
||||
|
||||
if ($config['site_type'] === 'mofang') {
|
||||
require_once __DIR__ . '/mofangidc.php';
|
||||
$success = refreshVpsListForConfig($configId);
|
||||
$typeName = '魔方平台';
|
||||
} elseif ($config['site_type'] === 'tencent') {
|
||||
require_once __DIR__ . '/tencentcloud.php';
|
||||
// 同时刷新CVM和轻量
|
||||
$cvmSuccess = refreshTencentCvmListForConfig($configId);
|
||||
$lhSuccess = refreshTencentLighthouseListForConfig($configId);
|
||||
$success = $cvmSuccess || $lhSuccess;
|
||||
$typeName = '腾讯云';
|
||||
} elseif ($config['site_type'] === 'aliyun') {
|
||||
require_once __DIR__ . '/aliyun.php';
|
||||
$success = refreshAliyunEcsListForConfig($configId);
|
||||
$typeName = '阿里云ECS';
|
||||
} elseif ($config['site_type'] === 'aliyun_swas') {
|
||||
require_once __DIR__ . '/aliyun.php';
|
||||
$success = refreshAliyunSwasListForConfig($configId);
|
||||
$typeName = '阿里云轻量';
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
$message = '<div class="success-message"><h3>✅ 刷新成功</h3><p>已刷新配置「' . htmlspecialchars($config['api_label']) . '」(' . $typeName . ')的VPS列表</p></div>';
|
||||
} else {
|
||||
$message = '<div class="error-message"><h3>❌ 刷新失败</h3><p>配置「' . htmlspecialchars($config['api_label']) . '」刷新失败,请检查API凭证和网络连接</p></div>';
|
||||
}
|
||||
} else {
|
||||
$message = '<div class="error-message">❌ 配置不存在</div>';
|
||||
}
|
||||
} else {
|
||||
$message = '<div class="error-message">❌ 无效的配置ID</div>';
|
||||
}
|
||||
} elseif ($action === 'refresh_vps_list') {
|
||||
// 手动刷新VPS列表
|
||||
// 手动刷新VPS列表(全部)
|
||||
$count = 0;
|
||||
|
||||
// 刷新魔方平台的VPS列表
|
||||
@ -201,6 +245,12 @@ foreach ($vpsList as $vps) {
|
||||
$vpsByApiLabel[$apiLabel][] = $vps;
|
||||
}
|
||||
|
||||
// 构建api_label到config_id的映射(用于单独刷新)
|
||||
$apiLabelToConfigId = [];
|
||||
foreach ($configs as $config) {
|
||||
$apiLabelToConfigId[$config['api_label']] = $config['id'];
|
||||
}
|
||||
|
||||
// 统计信息
|
||||
$totalCount = count($vpsList);
|
||||
$runningCount = 0;
|
||||
@ -245,6 +295,11 @@ foreach ($vpsList as $vps) {
|
||||
.btn-refresh:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.config-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
/* 消息自动消失动画 */
|
||||
.success-message, .error-message {
|
||||
transition: opacity 0.5s ease-out;
|
||||
@ -417,9 +472,9 @@ foreach ($vpsList as $vps) {
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<div class="toolbar">
|
||||
<form method="POST" style="display: inline;">
|
||||
<form method="POST" style="display: inline;" onsubmit="return confirmRefreshAll()">
|
||||
<button type="submit" name="action" value="refresh_vps_list" class="btn-refresh">
|
||||
🔄 手动刷新VPS列表
|
||||
🔄 刷新全部列表
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@ -454,13 +509,21 @@ foreach ($vpsList as $vps) {
|
||||
<?php foreach ($vpsByApiLabel as $apiLabel => $labelVps): ?>
|
||||
<div class="config-section">
|
||||
<div class="config-title">
|
||||
<?php echo htmlspecialchars($apiLabel); ?>
|
||||
- <?php echo count($labelVps); ?> 台VPS
|
||||
<span>
|
||||
<?php echo htmlspecialchars($apiLabel); ?>
|
||||
- <?php echo count($labelVps); ?> 台VPS
|
||||
</span>
|
||||
<form method="POST" style="display: inline; margin-left: 15px;" onsubmit="return confirm('确认刷新此配置的VPS列表?')">
|
||||
<input type="hidden" name="config_id" value="<?php echo $apiLabelToConfigId[$apiLabel] ?? 0; ?>">
|
||||
<button type="submit" name="action" value="refresh_single_config" class="btn-refresh" style="padding: 5px 12px; font-size: 13px;">
|
||||
🔄 刷新此配置
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if (empty($labelVps)): ?>
|
||||
<div class="empty-state" style="background: white; padding: 40px;">
|
||||
<p>此配置下暂无VPS,请点击“手动刷新VPS列表”获取</p>
|
||||
<p>此配置下暂无VPS,请点击右上角“🔄 刷新此配置”按钮获取</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="vps-grid">
|
||||
@ -627,6 +690,17 @@ foreach ($vpsList as $vps) {
|
||||
}, 5000); // 5秒后开始淡出
|
||||
});
|
||||
});
|
||||
|
||||
// 刷新全部列表确认
|
||||
function confirmRefreshAll() {
|
||||
return confirm('⚠️ 警告:资源消耗占用较高\n\n' +
|
||||
'刷新全部列表会同时请求所有配置的API,可能会导致:\n' +
|
||||
'• 页面卡顿或响应缓慢\n' +
|
||||
'• API超时导致报错中断\n' +
|
||||
'• 部分配置刷新失败\n\n' +
|
||||
'建议优先使用分离式刷新功能(点击每个配置右上角的🔄按钮)\n\n' +
|
||||
'确定要继续刷新全部列表吗?');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user