From 925456cced5156356da149912d9eaf3b286eaf0c Mon Sep 17 00:00:00 2001 From: MasonLiu <2857911564@qq.com> Date: Sun, 24 May 2026 03:21:39 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/index.php | 494 +++++++++++++++++++++++++++++++++++++++++ web/static/favicon.ico | Bin 0 -> 38700 bytes web/static/initial.css | 121 ++++++++++ web/static/style.css | 338 ++++++++++++++++++++++++++++ 4 files changed, 953 insertions(+) create mode 100644 web/index.php create mode 100644 web/static/favicon.ico create mode 100644 web/static/initial.css create mode 100644 web/static/style.css diff --git a/web/index.php b/web/index.php new file mode 100644 index 0000000..4c4f95b --- /dev/null +++ b/web/index.php @@ -0,0 +1,494 @@ + + + + + + + + + 初始配置 - 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/web/static/favicon.ico b/web/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..edab23335eaaa20dd24680d1fb718bef94e5a7d5 GIT binary patch literal 38700 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 literal 0 HcmV?d00001 diff --git a/web/static/initial.css b/web/static/initial.css new file mode 100644 index 0000000..70d47b1 --- /dev/null +++ b/web/static/initial.css @@ -0,0 +1,121 @@ +* { + 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/web/static/style.css b/web/static/style.css new file mode 100644 index 0000000..9e955c0 --- /dev/null +++ b/web/static/style.css @@ -0,0 +1,338 @@ +* { + 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