prepare("SELECT setting_value FROM settings WHERE setting_key = 'lubansms_apikey'"); $stmt->execute(); $db_apikey = $stmt->fetchColumn(); // Fallback if direct match fails if (!$db_apikey) { $settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR); foreach ($settings as $k => $v) { if (strpos($k, 'lubansms_apikey') !== false) { $db_apikey = trim($v); break; } } } } catch (Exception $e) {} $api = new LubanSMS($db_apikey); $action = $_GET['action'] ?? ''; header('Content-Type: application/json; charset=utf-8'); // Basic Auth check if (!isset($_SESSION['user_id']) && $action !== 'login') { echo json_encode(['code' => 401, 'msg' => '未登录或登录已过期']); exit; } try { switch ($action) { case 'get_balance': $stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); $balance = $stmt->fetchColumn(); echo json_encode(['code' => 0, 'balance' => number_format((float)$balance, 2)]); break; case 'get_countries': $res = $api->getCountries(); echo json_encode(['code' => 0, 'data' => $res['msg'] ?? $res['data'] ?? []], JSON_UNESCAPED_UNICODE); break; case 'get_services': $country = $_GET['country'] ?? ''; $service = $_GET['service'] ?? ''; $res = $api->getServices($country, $service); if ($res && (int)($res['code'] ?? -1) === 0) { $data = $res['msg'] ?? $res['data'] ?? []; if (!is_array($data)) $data = []; foreach ($data as &$item) { if (isset($item['cost'])) { $item['cost'] = round((float)$item['cost'] * PRICE_MULTIPLIER, 2); } } echo json_encode(['code' => 0, 'data' => $data], JSON_UNESCAPED_UNICODE); } else { echo json_encode($res ?: ['code' => 500, 'msg' => '获取项目列表失败'], JSON_UNESCAPED_UNICODE); } break; case 'get_number': $service_id = $_GET['service_id'] ?? ''; $country_name = $_GET['country_name'] ?? '未知国家'; $service_name = $_GET['service_name'] ?? '未知项目'; $price = (float)($_GET['price'] ?? 0); $stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); $balance = (float)$stmt->fetchColumn(); if ($balance < $price) { echo json_encode(['code' => 400, 'msg' => '余额不足,请先充值']); break; } $res = $api->getNumber($service_id); if ($res && (int)($res['code'] ?? -1) === 0) { $pdo->beginTransaction(); try { $stmt = $pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ?"); $stmt->execute([$price, $_SESSION['user_id']]); $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(); echo json_encode($res, JSON_UNESCAPED_UNICODE); } catch (Exception $e) { $pdo->rollBack(); echo json_encode(['code' => 500, 'msg' => '数据库事务错误'], JSON_UNESCAPED_UNICODE); } } else { echo json_encode($res ?: ['code' => 500, 'msg' => 'API获取号码失败'], JSON_UNESCAPED_UNICODE); } break; case 'check_sms': $request_id = $_GET['request_id'] ?? ''; $res = $api->getSms($request_id); if ($res && (int)($res['code'] ?? -1) === 0 && (string)($res['msg'] ?? '') === 'success') { $stmt = $pdo->prepare("UPDATE sms_orders SET sms_content = ?, status = 'received' WHERE request_id = ?"); $stmt->execute([$res['sms_code'], $request_id]); } echo json_encode($res ?: ['code' => 500, 'msg' => 'API Error'], JSON_UNESCAPED_UNICODE); break; case 'create_recharge': $amount = (float)($_POST['amount'] ?? 0); if ($amount < 10) { echo json_encode(['code' => 400, 'msg' => '最低充值金额为 10 USDT']); break; } $final_amount = floor($amount) + (rand(1, 99) / 100); $stmt = $pdo->prepare("INSERT INTO recharges (user_id, amount, txid, status) VALUES (?, ?, 'Manual/Auto', 'pending')"); $stmt->execute([$_SESSION['user_id'], $final_amount]); echo json_encode(['code' => 0, 'recharge_id' => $pdo->lastInsertId(), 'amount' => $final_amount]); break; case 'check_recharge_status': $recharge_id = $_GET['recharge_id'] ?? ''; $stmt = $pdo->prepare("SELECT * FROM recharges WHERE id = ? AND user_id = ?"); $stmt->execute([$recharge_id, $_SESSION['user_id']]); $recharge = $stmt->fetch(); if (!$recharge) { echo json_encode(['code' => 404, 'msg' => '未找到充值订单']); break; } if ($recharge['status'] === 'completed') { echo json_encode(['code' => 0, 'status' => 'completed']); break; } echo json_encode(['code' => 0, 'status' => 'pending']); break; case 'send_message': $message = trim($_POST['message'] ?? ''); $target_user_id = $_POST['user_id'] ?? $_SESSION['user_id']; if (!$message) { echo json_encode(['code' => 400, 'msg' => '消息内容不能为空']); break; } $stmt = $pdo->prepare("SELECT role FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); $role = $stmt->fetchColumn(); $sender = ($role === 'admin') ? 'admin' : 'user'; $stmt = $pdo->prepare("INSERT INTO support_messages (user_id, sender, message, `is_read`) VALUES (?, ?, ?, 0)"); $stmt->execute([$target_user_id, $sender, $message]); echo json_encode(['code' => 0, 'msg' => '已发送']); break; case 'get_messages': $target_user_id = $_GET['user_id'] ?? $_SESSION['user_id']; $stmt = $pdo->prepare("SELECT role FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); $isAdmin = ($stmt->fetchColumn() === 'admin'); if (!$isAdmin && (int)$target_user_id !== (int)$_SESSION['user_id']) { echo json_encode(['code' => 403, 'msg' => 'Forbidden']); break; } if ($isAdmin && (int)$target_user_id !== (int)$_SESSION['user_id']) { $pdo->prepare("UPDATE support_messages SET `is_read` = 1 WHERE user_id = ? AND sender = 'user'")->execute([$target_user_id]); } else if (!$isAdmin) { $pdo->prepare("UPDATE support_messages SET `is_read` = 1 WHERE user_id = ? AND sender = 'admin'")->execute([$_SESSION['user_id']]); } $stmt = $pdo->prepare("SELECT * FROM support_messages WHERE user_id = ? ORDER BY id ASC"); $stmt->execute([$target_user_id]); echo json_encode(['code' => 0, 'data' => $stmt->fetchAll()]); break; case 'get_chat_users': $stmt = $pdo->prepare("SELECT role FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); if ($stmt->fetchColumn() !== 'admin') { echo json_encode(['code' => 403, 'msg' => 'Forbidden']); break; } // Optimized query to get last message reliably $stmt = $pdo->query(" SELECT u.id, u.username, m.message as last_message, m.created_at as last_time, (SELECT COUNT(*) FROM support_messages WHERE user_id = u.id AND sender = 'user' AND `is_read` = 0) as unread_count FROM users u JOIN (SELECT user_id, MAX(id) as max_id FROM support_messages GROUP BY user_id) last_msg_idx ON u.id = last_msg_idx.user_id JOIN support_messages m ON m.id = last_msg_idx.max_id ORDER BY m.id DESC "); echo json_encode(['code' => 0, 'data' => $stmt->fetchAll()]); break; case 'check_new_messages': $stmt = $pdo->prepare("SELECT role FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); $role = $stmt->fetchColumn(); if ($role === 'admin') { $stmt = $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.`is_read` = 0 ORDER BY m.id DESC LIMIT 1 "); $last_unread = $stmt->fetch(PDO::FETCH_ASSOC); $total_unread = $pdo->query("SELECT COUNT(*) FROM support_messages WHERE sender = 'user' AND `is_read` = 0")->fetchColumn(); echo json_encode(['code' => 0, 'unread_total' => $total_unread, 'last_user' => $last_unread['username'] ?? '']); } else { $stmt = $pdo->prepare("SELECT COUNT(*) FROM support_messages WHERE user_id = ? AND sender = 'admin' AND `is_read` = 0"); $stmt->execute([$_SESSION['user_id']]); echo json_encode(['code' => 0, 'unread_total' => $stmt->fetchColumn()]); } break; default: echo json_encode(['code' => 404, 'msg' => '未知请求']); break; } } catch (Exception $e) { echo json_encode(['code' => 500, 'msg' => $e->getMessage()]); }