38350-vm/spot.php
2026-02-11 08:19:17 +00:00

232 lines
14 KiB
PHP

<?php
session_start();
include 'header.php';
require_once 'db/config.php';
$user_id = $_SESSION['user_id'] ?? null;
$balance = 0;
if ($user_id) {
$stmt = db()->prepare("SELECT balance FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
$balance = $user['balance'] ?? 0;
}
?>
<div class="spot-trading-layout" style="display: grid; grid-template-columns: 280px 1fr 300px 300px; height: calc(100vh - 64px); background: #0b0e11; overflow: hidden; color: #EAECEF;">
<!-- Column 1: Pairs List -->
<div style="border-right: 1px solid #1e2329; display: flex; flex-direction: column; background: #161a1e;">
<div style="padding: 15px; border-bottom: 1px solid #1e2329;">
<input type="text" id="pair-search" placeholder="Search Markets" style="width: 100%; background: #0b0e11; border: 1px solid #2b3139; color: white; padding: 8px 12px; border-radius: 4px; font-size: 13px;">
</div>
<div id="pairs-list" style="flex: 1; overflow-y: auto;">
<!-- JS Filled -->
</div>
</div>
<!-- Column 2: K-Line & Orders -->
<div style="display: flex; flex-direction: column; border-right: 1px solid #1e2329; overflow: hidden;">
<!-- Top Info Bar -->
<div style="height: 60px; border-bottom: 1px solid #1e2329; display: flex; align-items: center; padding: 0 20px; gap: 30px; background: #161a1e;">
<div style="display: flex; align-items: center; gap: 10px;">
<img id="current-icon" src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" width="24">
<span style="font-weight: bold; font-size: 1.1rem;" id="current-pair">BTC/USDT</span>
</div>
<div style="display: flex; gap: 20px;">
<div class="stat-box"><div id="top-price" style="font-weight: bold; color: #00c087;">--.---</div><div style="font-size: 10px; color: #848e9c;">Price</div></div>
<div class="stat-box"><div id="top-change" style="font-weight: bold;">--%</div><div style="font-size: 10px; color: #848e9c;">24h Change</div></div>
<div class="stat-box"><div id="top-high" style="color: white;">--.---</div><div style="font-size: 10px; color: #848e9c;">24h High</div></div>
<div class="stat-box"><div id="top-low" style="color: white;">--.---</div><div style="font-size: 10px; color: #848e9c;">24h Low</div></div>
</div>
</div>
<!-- K-Line -->
<div id="tradingview_chart" style="flex: 1;"></div>
<!-- Orders Tabs -->
<div style="height: 300px; border-top: 1px solid #1e2329; display: flex; flex-direction: column; background: #161a1e;">
<div style="display: flex; border-bottom: 1px solid #1e2329;">
<div class="order-tab active" onclick="switchOrderTab(this, 'open')"><?php echo __('open_orders'); ?></div>
<div class="order-tab" onclick="switchOrderTab(this, 'history')"><?php echo __('order_history'); ?></div>
<div class="order-tab" onclick="switchOrderTab(this, 'trades')"><?php echo __('trade_history'); ?></div>
<div class="order-tab" onclick="switchOrderTab(this, 'funds')"><?php echo __('funds_flow'); ?></div>
</div>
<div style="flex: 1; overflow-y: auto; padding: 15px;">
<table style="width: 100%; font-size: 12px; color: #848e9c; text-align: left;">
<thead>
<tr style="border-bottom: 1px solid #1e2329;">
<th style="padding-bottom: 8px;">Time</th>
<th style="padding-bottom: 8px;">Type</th>
<th style="padding-bottom: 8px;">Side</th>
<th style="padding-bottom: 8px;">Price</th>
<th style="padding-bottom: 8px;">Amount</th>
<th style="padding-bottom: 8px;">Filled</th>
<th style="padding-bottom: 8px;">Total</th>
<th style="padding-bottom: 8px;">Status</th>
</tr>
</thead>
<tbody id="orders-list-body">
<tr><td colspan="8" style="text-align: center; padding: 30px; opacity: 0.5;">No active orders</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Column 3: Order Panel -->
<div style="border-right: 1px solid #1e2329; background: #161a1e; display: flex; flex-direction: column; padding: 20px;">
<div style="font-size: 14px; font-weight: bold; margin-bottom: 20px;"><?php echo __('trade_panel'); ?></div>
<div style="display: flex; background: #2b3139; border-radius: 4px; margin-bottom: 20px;">
<button class="trade-type-btn active" style="flex: 1; padding: 8px; border: none; background: transparent; color: white; cursor: pointer;">Limit</button>
<button class="trade-type-btn" style="flex: 1; padding: 8px; border: none; background: transparent; color: #848e9c; cursor: pointer;">Market</button>
</div>
<div style="margin-bottom: 10px; font-size: 12px; color: #848e9c; display: flex; justify-content: space-between;">
<span>Balance</span>
<span style="color: white;"><?php echo number_format($balance, 2); ?> USDT</span>
</div>
<!-- Buy -->
<div style="margin-bottom: 25px;">
<div class="input-wrap"><span>Price</span><input type="number" id="buy-price" placeholder="0.00"><span>USDT</span></div>
<div class="input-wrap"><span>Amount</span><input type="number" id="buy-amount" placeholder="0.00"><span id="buy-token">BTC</span></div>
<div style="margin: 15px 0;"><input type="range" class="slider" style="width: 100%;"></div>
<button class="trade-btn buy" onclick="placeOrder('buy')">Buy <span class="buy-symbol">BTC</span></button>
</div>
<!-- Sell -->
<div>
<div class="input-wrap"><span>Price</span><input type="number" id="sell-price" placeholder="0.00"><span>USDT</span></div>
<div class="input-wrap"><span>Amount</span><input type="number" id="sell-amount" placeholder="0.00"><span id="sell-token">BTC</span></div>
<div style="margin: 15px 0;"><input type="range" class="slider" style="width: 100%;"></div>
<button class="trade-btn sell" onclick="placeOrder('sell')">Sell <span class="sell-symbol">BTC</span></button>
</div>
</div>
<!-- Column 4: Order Book -->
<div style="background: #161a1e; display: flex; flex-direction: column;">
<div style="padding: 15px; border-bottom: 1px solid #1e2329; font-size: 14px; font-weight: bold;">Order Book</div>
<div style="padding: 10px 15px; font-size: 11px; color: #848e9c; display: flex; justify-content: space-between;">
<span>Price(USDT)</span>
<span>Amount(BTC)</span>
</div>
<div style="flex: 1; overflow: hidden; display: flex; flex-direction: column;">
<div id="asks" style="flex: 1; display: flex; flex-direction: column-reverse; padding: 0 15px; overflow: hidden; font-family: monospace;"></div>
<div id="mid-price" style="padding: 12px; text-align: center; font-size: 1.1rem; font-weight: bold; color: #00c087; background: rgba(255,255,255,0.03);">--.---</div>
<div id="bids" style="flex: 1; display: flex; flex-direction: column; padding: 0 15px; overflow: hidden; font-family: monospace;"></div>
</div>
</div>
</div>
<style>
.stat-box { border-left: 1px solid #2b3139; padding-left: 15px; display: flex; flex-direction: column; }
.order-tab { padding: 10px 15px; font-size: 12px; color: #848e9c; cursor: pointer; border-bottom: 2px solid transparent; }
.order-tab.active { color: var(--primary-color); border-bottom-color: var(--primary-color); }
.input-wrap { background: #0b0e11; border: 1px solid #2b3139; border-radius: 4px; padding: 8px 12px; display: flex; align-items: center; margin-bottom: 12px; gap: 10px; }
.input-wrap span { font-size: 12px; color: #848e9c; white-space: nowrap; width: 45px; }
.input-wrap input { background: transparent; border: none; color: white; flex: 1; text-align: right; outline: none; font-weight: bold; }
.trade-btn { width: 100%; padding: 12px; border: none; border-radius: 4px; font-weight: bold; cursor: pointer; color: white; }
.trade-btn.buy { background: #00c087; }
.trade-btn.sell { background: #f6465d; }
.slider { -webkit-appearance: none; height: 3px; background: #2b3139; border-radius: 2px; }
.slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; background: white; border-radius: 50%; }
</style>
<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>
<script>
let currentSymbol = 'BTCUSDT';
let currentPrice = 0;
const pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT', 'ADAUSDT', 'DOGEUSDT', 'DOTUSDT', 'LINKUSDT', 'LTCUSDT', 'MATICUSDT'];
function initChart(symbol) {
new TradingView.widget({
"width": "100%", "height": "100%", "symbol": "BINANCE:" + symbol, "interval": "15", "timezone": "Etc/UTC", "theme": "dark", "style": "1", "locale": "<?php echo $lang == 'zh' ? 'zh_CN' : 'en'; ?>", "container_id": "tradingview_chart", "backgroundColor": "#0b0e11", "gridColor": "rgba(42, 46, 57, 0.05)", "hide_side_toolbar": false, "allow_symbol_change": false, "save_image": false
});
}
initChart(currentSymbol);
const ws = new WebSocket('wss://stream.binance.com:9443/ws/' + pairs.map(p => p.toLowerCase() + '@ticker').join('/'));
const marketData = {};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const s = data.s;
marketData[s] = data;
renderPairsList();
if (s === currentSymbol) {
currentPrice = parseFloat(data.c);
document.getElementById('top-price').innerText = currentPrice.toLocaleString();
document.getElementById('top-price').style.color = data.P >= 0 ? '#00c087' : '#f6465d';
document.getElementById('top-change').innerText = (data.P >= 0 ? '+' : '') + data.P + '%';
document.getElementById('top-change').style.color = data.P >= 0 ? '#00c087' : '#f6465d';
document.getElementById('top-high').innerText = parseFloat(data.h).toLocaleString();
document.getElementById('top-low').innerText = parseFloat(data.l).toLocaleString();
document.getElementById('mid-price').innerText = currentPrice.toLocaleString();
updateOrderBook(currentPrice);
}
};
function renderPairsList() {
const list = document.getElementById('pairs-list');
let html = '';
pairs.forEach(p => {
const d = marketData[p] || {c: 0, P: 0};
const color = d.P >= 0 ? '#00c087' : '#f6465d';
const name = p.replace('USDT', '');
html += `
<div onclick="changePair('${p}')" style="display: flex; justify-content: space-between; padding: 12px 15px; cursor: pointer; border-bottom: 1px solid #1e2329; ${currentSymbol === p ? 'background: #2b3139;' : ''}">
<div style="display: flex; gap: 8px; align-items: center;">
<img src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png" width="18" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
<span style="font-weight: bold; font-size: 13px;">${name}</span>
</div>
<div style="text-align: right;">
<div style="font-size: 13px;">${parseFloat(d.c).toLocaleString()}</div>
<div style="color: ${color}; font-size: 11px;">${d.P >= 0 ? '+' : ''}${d.P}%</div>
</div>
</div>
`;
});
list.innerHTML = html;
}
function changePair(pair) {
currentSymbol = pair;
const name = pair.replace('USDT', '');
document.getElementById('current-pair').innerText = name + '/USDT';
document.getElementById('current-icon').src = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png`;
document.getElementById('buy-token').innerText = name;
document.getElementById('sell-token').innerText = name;
document.querySelectorAll('.buy-symbol, .sell-symbol').forEach(el => el.innerText = name);
initChart(pair);
renderPairsList();
}
function updateOrderBook(price) {
let asksHtml = ''; let bidsHtml = '';
for(let i=1; i<=20; i++) {
const askPrice = (price + (i * 0.01 * price / 100)).toFixed(2);
const bidPrice = (price - (i * 0.01 * price / 100)).toFixed(2);
asksHtml += `<div style="display: flex; justify-content: space-between; font-size: 11px; padding: 2px 0;"><span style="color: #f6465d;">${askPrice}</span><span style="color: #848e9c;">${(Math.random()*1).toFixed(4)}</span></div>`;
bidsHtml += `<div style="display: flex; justify-content: space-between; font-size: 11px; padding: 2px 0;"><span style="color: #00c087;">${bidPrice}</span><span style="color: #848e9c;">${(Math.random()*1).toFixed(4)}</span></div>`;
}
document.getElementById('asks').innerHTML = asksHtml;
document.getElementById('bids').innerHTML = bidsHtml;
}
async function placeOrder(side) {
const price = parseFloat(document.getElementById(side + '-price').value) || currentPrice;
const amount = parseFloat(document.getElementById(side + '-amount').value);
if (!amount) return alert('Please enter amount');
const response = await fetch('api/place_order.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ symbol: currentSymbol, type: 'spot', side: side, order_type: 'limit', price: price, amount: amount, total: price * amount })
});
const result = await response.json();
if (result.success) { alert('Order placed!'); location.reload(); } else { alert('Error: ' + result.error); }
}
</script>
<?php include 'footer.php'; ?>