diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index edab233..0000000 Binary files a/favicon.ico and /dev/null differ diff --git a/index.php b/index.php deleted file mode 100644 index 61f9ed9..0000000 --- a/index.php +++ /dev/null @@ -1,494 +0,0 @@ - - - - - - - - - 初始配置 - VPS管理面板 - - -
-
-

🔧 初始配置

-

请填写以下信息以开始使用

-
- - -
- ❌ -
- - -
- 💡 提示:这些信息将保存在 config.php 文件中,请妥善保管。
- 若您需要重置或更改配置,请删除 config.php 文件并重新运行。
- 配置完成后请以该格式访问服务:example.com/?pass=API_PASS -
- -
-
- - -
用于保护管理面板的访问权限
可选:字母(a-z,A-Z)和数字(0-9)
-
- -
- - -
您的核云IDC登录账号
-
- -
- - -
在核云IDC控制台获取的API密钥
-
- - -
-
- - - - - ACCOUNT, - 'password' => API_KEY - ]; - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - if ($httpCode !== 200) { - return null; - } - - $result = json_decode($response, true); - $token = isset($result['jwt']) ? $result['jwt'] : null; - - // 保存新Token到缓存 - if ($token) { - saveTokenToCache($token); - } - - return $token; -} - -// ==================== 功能实现区域 ==================== - -/** - * 发送API请求 - */ -function sendApiRequest($endpoint, $method = 'GET', $data = []) { - $token = getLoginToken(); - if (!$token) { - return ['status' => 500, 'msg' => '获取Token失败,请检查账号和密码配置']; - } - - $url = BASE_URL . $endpoint; - $headers = [ - 'Authorization: JWT ' . $token, - 'Content-Type: application/json' - ]; - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - - if ($method === 'POST') { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); - } elseif ($method === 'PUT') { - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); - } - - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - return json_decode($response, true); -} - -/** - * 获取VPS列表 - */ -function getHostList($page = 1, $limit = 100) { - return sendApiRequest("/hosts?page={$page}&limit={$limit}", 'GET'); -} - -/** - * 获取VPS状态 - */ -function getHostStatus($hostId) { - return sendApiRequest("/hosts/{$hostId}/module/status?type=host", 'GET'); -} - -/** - * 操作VPS - */ -function operateHost($hostId, $operation) { - return sendApiRequest("/hosts/{$hostId}/module/{$operation}", 'PUT'); -} - -// ==================== 主逻辑区域 ==================== - -// 验证pass参数 -$pass = isset($_GET['pass']) ? $_GET['pass'] : ''; - -if ($pass !== API_PASS) { - header('Content-Type: application/json; charset=utf-8'); - echo json_encode(['status' => 403, 'msg' => '访问密码错误或者未输入密码,请拼接?pass=API_PASS后再尝试访问'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - exit; -} - -// 处理操作请求 -$action = isset($_POST['action']) ? $_POST['action'] : ''; -$hostId = isset($_POST['host_id']) ? intval($_POST['host_id']) : 0; - -$result = null; -if ($action && $hostId > 0) { - if ($action === 'reboot') { - $result = operateHost($hostId, 'hard_reboot'); - } elseif ($action === 'on') { - $result = operateHost($hostId, 'on'); - } elseif ($action === 'off') { - $result = operateHost($hostId, 'off'); - } -} - -// 获取VPS列表和状态 -$hosts = []; -$statusMap = []; -$domainstatus = []; -$totalCount = 0; -$errorMsg = ''; - -$listResult = getHostList(); -if (isset($listResult['status']) && $listResult['status'] === 200) { - $data = $listResult['data']; - $hosts = $data['host']; - $domainstatus = $data['domainstatus']; - $totalCount = $data['total']; - - // 批量获取所有VPS的状态 - foreach ($hosts as $host) { - $statusResult = getHostStatus($host['id']); - if (isset($statusResult['status']) && $statusResult['status'] === 200) { - $statusMap[$host['id']] = $statusResult['data']; - } else { - $statusMap[$host['id']] = ['status' => 'unknown', 'des' => '未知']; - } - } -} else { - $errorMsg = isset($listResult['msg']) ? $listResult['msg'] : '获取VPS列表失败'; -} - -header('Content-Type: text/html; charset=utf-8'); -?> - - - - - - - - VPS管理面板 - - -
-
-

🖥️ 核云IDC VPS管理面板

-

实时查看和管理您的云服务器

-
- -
- -
-

❌ 加载失败

-

-
- - - - -
-

✅ 操作成功

-

VPS # 已成功执行操作

-
- -
-

❌ 操作失败

-

-
- - - - -
- ✅ Token缓存生效中 | 剩余有效期:约 分钟 -
- - -
-
- 总计: 台服务器 -
-
- 运行中: 台 -
-
- 已关机: 台 -
-
- -
- $statusKey, 'color' => '#999']; - $powerStatus = isset($statusMap[$host['id']]) ? $statusMap[$host['id']] : ['status' => 'unknown', 'des' => '未知']; - - $regDate = date('Y-m-d', $host['regdate']); - $nextDueDate = date('Y-m-d', $host['nextduedate']); - - $powerClass = 'power-unknown'; - if ($powerStatus['status'] === 'on') { - $powerClass = 'power-on'; - } elseif ($powerStatus['status'] === 'off') { - $powerClass = 'power-off'; - } - ?> -
-
-
#
- - - -
- -
-
- 域名 - -
-
- IP地址 - -
-
- 产品名称 - -
-
- 注册日期 - -
-
- 到期日期 - -
-
- 金额 - ¥ -
-
- 计费周期 - -
-
- -
- - -
- -
- -
- - - -
-
-
- -
- -
-
- - \ No newline at end of file diff --git a/initial.css b/initial.css deleted file mode 100644 index 60208d5..0000000 --- a/initial.css +++ /dev/null @@ -1,121 +0,0 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; - padding: 20px; -} - -.config-container { - background: white; - border-radius: 16px; - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); - padding: 40px; - max-width: 500px; - width: 100%; -} - -.config-header { - text-align: center; - margin-bottom: 30px; -} - -.config-header h1 { - color: #2d3748; - font-size: 24px; - margin-bottom: 10px; -} - -.config-header p { - color: #718096; - font-size: 14px; -} - -.form-group { - margin-bottom: 20px; -} - -.form-group label { - display: block; - color: #4a5568; - font-weight: 600; - margin-bottom: 8px; - font-size: 14px; -} - -.form-group input { - width: 100%; - padding: 12px 16px; - border: 2px solid #e2e8f0; - border-radius: 8px; - font-size: 14px; - transition: all 0.3s; -} - -.form-group input:focus { - outline: none; - border-color: #667eea; - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); -} - -.form-group .help-text { - color: #a0aec0; - font-size: 12px; - margin-top: 6px; -} - -.error-message { - background: #fed7d7; - border-left: 4px solid #f56565; - color: #c53030; - padding: 12px 16px; - border-radius: 8px; - margin-bottom: 20px; - font-size: 14px; -} - -.btn-submit { - width: 100%; - padding: 14px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border: none; - border-radius: 8px; - font-size: 16px; - font-weight: 600; - cursor: pointer; - transition: all 0.3s; -} - -.btn-submit:hover { - transform: translateY(-2px); - box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); -} - -.btn-submit:active { - transform: translateY(0); -} - -.info-box { - background: #ebf8ff; - border-left: 4px solid #4299e1; - padding: 12px 16px; - border-radius: 8px; - margin-bottom: 20px; - font-size: 13px; - color: #2c5282; -} - -@media (max-width: 480px) { - .config-container { - padding: 30px 20px; - } -} \ No newline at end of file diff --git a/style.css b/style.css deleted file mode 100644 index 3efb297..0000000 --- a/style.css +++ /dev/null @@ -1,338 +0,0 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; - background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); - min-height: 100vh; - padding: 10px; -} - -.container { - max-width: 1400px; - margin: 0 auto; - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(10px); - border-radius: 16px; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); - overflow: hidden; -} - -.header { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - padding: 25px 20px; - text-align: center; -} - -.header h1 { - font-size: 24px; - margin-bottom: 8px; - font-weight: 600; -} - -.header p { - opacity: 0.9; - font-size: 13px; -} - -.content { - padding: 20px; -} - -.token-info { - background: linear-gradient(135deg, #e0f7fa 0%, #b2ebf2 100%); - border-left: 4px solid #00bcd4; - padding: 12px 16px; - border-radius: 8px; - margin-bottom: 20px; - font-size: 13px; - color: #006064; -} - -.token-info strong { - color: #00838f; -} - -.stats-bar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 15px; - background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); - border-radius: 10px; - margin-bottom: 20px; - flex-wrap: wrap; - gap: 10px; -} - -.stats-item { - font-size: 14px; - color: #2d3748; -} - -.stats-item strong { - color: #667eea; - font-size: 18px; -} - -.card-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); - gap: 20px; -} - -.vps-card { - background: white; - border-radius: 12px; - padding: 20px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); - transition: all 0.3s ease; - border: 1px solid #e2e8f0; -} - -.vps-card:hover { - transform: translateY(-4px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); -} - -.card-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 15px; - padding-bottom: 12px; - border-bottom: 2px solid #f0f0f0; -} - -.vps-id { - font-size: 18px; - font-weight: 600; - color: #2d3748; -} - -.status-badge { - display: inline-block; - padding: 6px 14px; - border-radius: 20px; - color: white; - font-size: 12px; - font-weight: 600; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.card-body { - margin-bottom: 15px; -} - -.info-row { - display: flex; - justify-content: space-between; - padding: 8px 0; - border-bottom: 1px solid #f7fafc; - font-size: 13px; -} - -.info-row:last-child { - border-bottom: none; -} - -.info-label { - color: #718096; - font-weight: 500; -} - -.info-value { - color: #2d3748; - font-weight: 600; - text-align: right; - max-width: 60%; - word-break: break-all; -} - -.power-status { - display: flex; - align-items: center; - gap: 8px; - padding: 10px; - background: #f7fafc; - border-radius: 8px; - margin-bottom: 15px; -} - -.power-indicator { - width: 12px; - height: 12px; - border-radius: 50%; - display: inline-block; -} - -.power-on { - background: #48bb78; - box-shadow: 0 0 8px #48bb78; -} - -.power-off { - background: #e53e3e; - box-shadow: 0 0 8px #e53e3e; -} - -.power-unknown { - background: #a0aec0; -} - -.power-text { - font-size: 14px; - font-weight: 600; - color: #2d3748; -} - -.card-actions { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 10px; -} - -.btn { - padding: 10px 16px; - border: none; - border-radius: 8px; - cursor: pointer; - font-size: 13px; - font-weight: 600; - text-decoration: none; - color: white; - transition: all 0.3s; - text-align: center; - display: block; -} - -.btn:hover { - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); -} - -.btn:active { - transform: translateY(0); -} - -.btn-success { - background: linear-gradient(135deg, #48bb78 0%, #38a169 100%); -} - -.btn-warning { - background: linear-gradient(135deg, #ed8936 0%, #dd6b20 100%); -} - -.btn-danger { - background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%); -} - -.btn-info { - background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%); -} - -.error-message { - background: linear-gradient(135deg, #fed7d7 0%, #feb2b2 100%); - border-left: 4px solid #f56565; - color: #c53030; - padding: 20px; - border-radius: 8px; - text-align: center; -} - -.success-message { - background: linear-gradient(135deg, #c6f6d5 0%, #9ae6b4 100%); - border-left: 4px solid #48bb78; - color: #22543d; - padding: 20px; - border-radius: 8px; - text-align: center; - margin-bottom: 20px; -} - -.loading { - text-align: center; - padding: 40px; - color: #718096; -} - -.loading-spinner { - display: inline-block; - width: 40px; - height: 40px; - border: 4px solid #e2e8f0; - border-top-color: #667eea; - border-radius: 50%; - animation: spin 0.8s linear infinite; - margin-bottom: 15px; -} - -@keyframes spin { - to { transform: rotate(360deg); } -} - -/* 响应式设计 */ -@media (max-width: 768px) { - body { - padding: 5px; - } - - .header { - padding: 20px 15px; - } - - .header h1 { - font-size: 20px; - } - - .content { - padding: 15px; - } - - .card-grid { - grid-template-columns: 1fr; - gap: 15px; - } - - .vps-card { - padding: 15px; - } - - .card-actions { - grid-template-columns: 1fr; - } - - .stats-bar { - flex-direction: column; - align-items: flex-start; - } - - .info-row { - flex-direction: column; - gap: 4px; - } - - .info-value { - max-width: 100%; - text-align: left; - } -} - -@media (max-width: 480px) { - .header h1 { - font-size: 18px; - } - - .vps-id { - font-size: 16px; - } - - .btn { - padding: 8px 12px; - font-size: 12px; - } -} \ No newline at end of file