diff --git a/admin.php b/admin.php index ba05005..9200c6c 100644 --- a/admin.php +++ b/admin.php @@ -4,7 +4,6 @@ require_once __DIR__ . '/db/config.php'; $pdo = db(); -// Ensure user is admin if (!isset($_SESSION['user_id'])) { header('Location: index.php'); exit; @@ -19,7 +18,6 @@ if ($user['role'] !== 'admin') { $action = $_GET['action'] ?? 'dashboard'; -// Handle Actions if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($action === 'confirm_recharge') { $id = $_POST['id']; @@ -38,208 +36,241 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $id = $_POST['id']; $stmt = $pdo->prepare("UPDATE recharges SET status = 'rejected' WHERE id = ?"); $stmt->execute([$id]); - } elseif ($action === 'reply_support') { - $user_id = $_POST['user_id']; - $message = $_POST['message']; - $stmt = $pdo->prepare("INSERT INTO support_messages (user_id, sender, message) VALUES (?, 'admin', ?)"); - $stmt->execute([$user_id, $message]); } elseif ($action === 'update_settings') { foreach ($_POST['settings'] as $key => $value) { - $stmt = $pdo->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = ?"); - $stmt->execute([$value, $key]); + $stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = ?"); + $stmt->execute([$key, $value, $value]); } } } -// Fetch Data $stats = [ 'users' => $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn(), 'pending_recharges' => $pdo->query("SELECT COUNT(*) FROM recharges WHERE status = 'pending'")->fetchColumn(), 'total_orders' => $pdo->query("SELECT COUNT(*) FROM sms_orders")->fetchColumn(), + 'total_balance' => $pdo->query("SELECT SUM(balance) FROM users")->fetchColumn(), ]; $pending_recharges = $pdo->query("SELECT r.*, u.username FROM recharges r JOIN users u ON r.user_id = u.id WHERE r.status = 'pending' ORDER BY r.created_at DESC")->fetchAll(); -$support_requests = $pdo->query("SELECT m.*, u.username FROM support_messages m JOIN users u ON m.user_id = u.id WHERE m.sender = 'user' AND m.id IN (SELECT MAX(id) FROM support_messages GROUP BY user_id) ORDER BY m.created_at DESC")->fetchAll(); -$settings = $pdo->query("SELECT * FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR); +$settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR); ?> - 管理后台 - 全球接码 + 管理后台 - <?= htmlspecialchars($settings['site_name'] ?? '全球接码') ?> - +
-
+

'数据大盘', - 'recharges' => '充值申请列表', - 'support' => '用户咨询回复', - 'settings' => '全局系统设置' + 'dashboard' => '核心数据概览', + 'recharges' => '充值审核中心', + 'settings' => '系统全局参数配置' ][$action] ?>

-
系统时间:
-
-
-
-
注册用户总量
-

+
+
+
+
注册用户总量
+

-
-
-
待审核充值
-

+
+
+
待审核充值
+

-
-
-
累计成交订单
-

+
+
+
累计接码订单
+

+
+
+
+
+
系统用户总余额
+

$

-
+
- +
- - - - - + + + + + - - - - - + + + + - +
用户名申请金额交易 TXID提交时间操作决策用户信息 / USER申请金额 / AMOUNT交易 TXID / HASH提交时间 / TIME管理操作 / ACTION
$ -
+
+
+
USER_ID:
+
$ + - + -
+ - +
暂无待处理充值
目前暂无任何待处理的充值申请
- -
- -
-
-
-
- -
-
- -
-
- -
- - -
-
+ +
+
+
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
区块链支付钱包地址配置 / CRYPTO WALLETS
+ +
+ + +
+
+ + +
+ +
+ +
LUBAN SMS API 后端配置 / API GATEWAY
+
+ +
- - -
暂无待回复消息
- -
- -
- -
- $val): ?> -
- - -
- -
-
- +
+
diff --git a/ajax_handler.php b/ajax_handler.php index c187643..459dc77 100644 --- a/ajax_handler.php +++ b/ajax_handler.php @@ -3,6 +3,9 @@ session_start(); require_once __DIR__ . '/db/config.php'; require_once __DIR__ . '/api/LocalLubanApi.php'; +// Price multiplier to earn profit (User requested 1.5 - 2x) +const PRICE_MULTIPLIER = 1.8; + $pdo = db(); $api = new LubanSMS(); @@ -15,6 +18,39 @@ if (!isset($_SESSION['user_id']) && $action !== 'login') { exit; } +function check_trc20_payment($address, $target_amount, $order_time) { + if (!$address || $address == 'TEm1B...TRC20_ADDRESS_HERE') return false; + + // TronScan API to check transactions + $url = "https://apilist.tronscan.org/api/token_trc20/transfers?limit=20&start=0&direction=1&address=" . urlencode($address); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0'); + $response = curl_exec($ch); + curl_close($ch); + + if (!$response) return false; + $data = json_decode($response, true); + if (!isset($data['token_transfers'])) return false; + + foreach ($data['token_transfers'] as $tx) { + if ($tx['symbol'] !== 'USDT') continue; + + $amount = (float)$tx['quant'] / pow(10, $tx['tokenInfo']['tokenDecimal']); + $tx_time = (int)($tx['block_ts'] / 1000); + $order_ts = strtotime($order_time); + + // Match amount (with small tolerance for floating point) and time (must be after order) + if (abs($amount - $target_amount) < 0.001 && $tx_time > $order_ts) { + return $tx['transaction_id']; + } + } + return false; +} + switch ($action) { case 'get_balance': $stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ?"); @@ -24,13 +60,31 @@ switch ($action) { break; case 'get_countries': - echo json_encode($api->getCountries()); + $res = $api->getCountries(); + if ($res['code'] === 0 && isset($res['msg'])) { + $res['data'] = $res['msg']; + unset($res['msg']); + } + echo json_encode($res); break; case 'get_services': $country = $_GET['country'] ?? ''; $service = $_GET['service'] ?? ''; $res = $api->getServices($country, $service); + + if ($res['code'] === 0 && isset($res['msg'])) { + $res['data'] = $res['msg']; + unset($res['msg']); + } + + if ($res['code'] === 0 && isset($res['data'])) { + foreach ($res['data'] as &$item) { + if (isset($item['cost'])) { + $item['cost'] = round($item['cost'] * PRICE_MULTIPLIER, 2); + } + } + } echo json_encode($res); break; @@ -38,7 +92,7 @@ switch ($action) { $service_id = $_GET['service_id'] ?? ''; $country_name = $_GET['country_name'] ?? '未知国家'; $service_name = $_GET['service_name'] ?? '未知项目'; - $price = (float)($_GET['price'] ?? 1.0); + $price = (float)($_GET['price'] ?? 0); if (!$service_id) { echo json_encode(['code' => 400, 'msg' => 'Service ID is required']); @@ -61,7 +115,6 @@ switch ($action) { $stmt = $pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ?"); $stmt->execute([$price, $_SESSION['user_id']]); - // User requested 10 minutes countdown $stmt = $pdo->prepare("INSERT INTO sms_orders (user_id, request_id, number, service_name, country_name, cost, status, expire_at) VALUES (?, ?, ?, ?, ?, ?, 'pending', DATE_ADD(NOW(), INTERVAL 10 MINUTE))"); $stmt->execute([$_SESSION['user_id'], $res['request_id'], $res['number'], $service_name, $country_name, $price]); $pdo->commit(); @@ -93,7 +146,6 @@ switch ($action) { case 'release_number': $request_id = $_GET['request_id'] ?? ''; - // Manual release requires > 2 minutes $stmt = $pdo->prepare("SELECT created_at, status FROM sms_orders WHERE request_id = ? AND user_id = ?"); $stmt->execute([$request_id, $_SESSION['user_id']]); $order = $stmt->fetch(); @@ -110,7 +162,7 @@ switch ($action) { $createdAt = strtotime($order['created_at']); if (time() - $createdAt < 120) { - echo json_encode(['code' => 400, 'msg' => '获取号码不足2分钟,暂时无法手动释放。请稍候或等待系统自动释放。']); + echo json_encode(['code' => 400, 'msg' => '获取号码不足2分钟,暂时无法手动释放。']); break; } @@ -123,7 +175,6 @@ switch ($action) { break; case 'get_active_orders': - // Auto-expire orders $stmt = $pdo->prepare("UPDATE sms_orders SET status = 'expired' WHERE status = 'pending' AND expire_at < NOW()"); $stmt->execute(); @@ -139,9 +190,6 @@ switch ($action) { break; } - // Add random decimal to help identify payment (e.g. 10.42) - // If it already has decimals, we might want to keep it or refine it. - // The user said "any recharge add decimal". $base = floor($amount); $random_decimal = rand(1, 99) / 100; $final_amount = $base + $random_decimal; @@ -169,26 +217,26 @@ switch ($action) { if ($recharge['status'] === 'completed') { echo json_encode(['code' => 0, 'status' => 'completed']); - break; + exit; } - // SIMULATION: In a real app, this would query a blockchain API for the address. - // For testing, we'll auto-complete after 15 seconds. - $createdAt = strtotime($recharge['created_at']); - if (time() - $createdAt > 15) { + // Try Auto-Detection + $settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR); + $trc20_address = $settings['usdt_trc20_address'] ?? ''; + + $txid = check_trc20_payment($trc20_address, $recharge['amount'], $recharge['created_at']); + if ($txid) { $pdo->beginTransaction(); try { - $stmt = $pdo->prepare("UPDATE recharges SET status = 'completed' WHERE id = ?"); - $stmt->execute([$recharge_id]); - + $stmt = $pdo->prepare("UPDATE recharges SET status = 'completed', txid = ? WHERE id = ?"); + $stmt->execute([$txid, $recharge_id]); $stmt = $pdo->prepare("UPDATE users SET balance = balance + ? WHERE id = ?"); - $stmt->execute([$recharge['amount'], $_SESSION['user_id']]); - + $stmt->execute([$recharge['amount'], $recharge['user_id']]); $pdo->commit(); echo json_encode(['code' => 0, 'status' => 'completed']); } catch (Exception $e) { $pdo->rollBack(); - echo json_encode(['code' => 500, 'msg' => 'Database error']); + echo json_encode(['code' => 500, 'msg' => 'Detection error']); } } else { echo json_encode(['code' => 0, 'status' => 'pending']); @@ -198,4 +246,4 @@ switch ($action) { default: echo json_encode(['code' => 404, 'msg' => 'Action not found']); break; -} +} \ No newline at end of file diff --git a/assets/pasted-20260210-074218-c408deaa.png b/assets/pasted-20260210-074218-c408deaa.png new file mode 100644 index 0000000..5eeaf98 Binary files /dev/null and b/assets/pasted-20260210-074218-c408deaa.png differ diff --git a/assets/pasted-20260210-074819-9c0ead1f.png b/assets/pasted-20260210-074819-9c0ead1f.png new file mode 100644 index 0000000..7de1414 Binary files /dev/null and b/assets/pasted-20260210-074819-9c0ead1f.png differ diff --git a/assets/pasted-20260210-075800-30a55110.png b/assets/pasted-20260210-075800-30a55110.png new file mode 100644 index 0000000..e319f05 Binary files /dev/null and b/assets/pasted-20260210-075800-30a55110.png differ diff --git a/assets/pasted-20260210-080314-97487350.png b/assets/pasted-20260210-080314-97487350.png new file mode 100644 index 0000000..8241b9b Binary files /dev/null and b/assets/pasted-20260210-080314-97487350.png differ diff --git a/assets/pasted-20260210-082628-83f66727.png b/assets/pasted-20260210-082628-83f66727.png new file mode 100644 index 0000000..8d921db Binary files /dev/null and b/assets/pasted-20260210-082628-83f66727.png differ diff --git a/dashboard.php b/dashboard.php index 9de10bb..5d4980c 100644 --- a/dashboard.php +++ b/dashboard.php @@ -9,211 +9,236 @@ $pdo = db(); $stmt = $pdo->prepare("SELECT username, balance FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); $user = $stmt->fetch(); + +$settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR); +$notice_text = $settings['notice_text'] ?? '欢迎使用全球接码平台!'; ?> - 工作台 - 全球接码 (Global SMS) + 工作台 - <?= htmlspecialchars($settings['site_name'] ?? '全球接码') ?> @@ -222,125 +247,107 @@ $user = $stmt->fetch();
-
-
-

取号预约工作台 LIVE

-

选择地区和项目,即刻开启您的业务验证

-
-
-
- -
- 当前余额 (Balance) - $ -
+ - -
-
-
活动任务中心 (Activity Center)
-
- 数据同步中... - -
+
+
+ +
+
+ +
+
+ + + -
-
-
- -
-
- - -
-