// Global variables let currentMarketData = {}; // Translation helper for JS const translations = { 'en': { 'Buy': 'Buy', 'Sell': 'Sell', 'Trade': 'Trade', 'Price': 'Price', 'Amount': 'Amount' }, 'zh': { 'Buy': '买入', 'Sell': '卖出', 'Trade': '交易', 'Price': '价格', 'Amount': '数量' }, // ... add more as needed or fetch from server }; function getLang() { return document.documentElement.lang || 'en'; } function tj(key) { const lang = getLang(); return (translations[lang] && translations[lang][key]) || key; } // Market Data Fetching async function fetchMarketData() { try { const resp = await fetch('api/market_api.php'); const result = await resp.json(); if (result.success) { currentMarketData = result.data; updateUI(); } } catch (e) { console.error('Market API error', e); } } function updateUI() { // Update Trade Page if on it if (document.getElementById('crypto-list-container')) { updateTradePage(); } // Update Market Page if on it if (document.getElementById('all-market-body')) { updateMarketPage(); } } function updateTradePage() { const listContainer = document.getElementById('crypto-list-container'); const search = document.getElementById('market-search')?.value.toLowerCase() || ''; const currentSymbol = document.getElementById('current-symbol')?.value; let html = ''; Object.keys(currentMarketData).forEach(symbol => { if (symbol.toLowerCase().includes(search) || currentMarketData[symbol].name.toLowerCase().includes(search)) { const coin = currentMarketData[symbol]; const active = symbol === currentSymbol ? 'active' : ''; const changeClass = coin.change >= 0 ? 'text-success' : 'text-danger'; const changeSign = coin.change >= 0 ? '+' : ''; html += `
${symbol}
${coin.name}
$${coin.price.toLocaleString(undefined, {minimumFractionDigits: 2})}
${changeSign}${coin.change.toFixed(2)}%
`; } }); listContainer.innerHTML = html; // Update header info for current symbol if (currentSymbol && currentMarketData[currentSymbol]) { const coin = currentMarketData[currentSymbol]; const lastPriceEl = document.getElementById('last-price'); if (lastPriceEl) { const oldPrice = parseFloat(lastPriceEl.innerText.replace(/[$,]/g, '')) || 0; lastPriceEl.innerText = '$' + coin.price.toLocaleString(undefined, {minimumFractionDigits: 2}); lastPriceEl.className = coin.price >= oldPrice ? 'fw-bold text-success fs-5' : 'fw-bold text-danger fs-5'; const bookPriceEl = document.getElementById('book-price'); if (bookPriceEl) bookPriceEl.innerText = coin.price.toLocaleString(undefined, {minimumFractionDigits: 2}); } const changeEl = document.getElementById('24h-change'); if (changeEl) { changeEl.innerText = (coin.change >= 0 ? '+' : '') + coin.change.toFixed(2) + '%'; changeEl.className = 'fw-bold ' + (coin.change >= 0 ? 'text-success' : 'text-danger'); } // Mocking high/low/vol if (document.getElementById('24h-high')) document.getElementById('24h-high').innerText = '$' + (coin.price * 1.05).toLocaleString(undefined, {minimumFractionDigits: 2}); if (document.getElementById('24h-low')) document.getElementById('24h-low').innerText = '$' + (coin.price * 0.95).toLocaleString(undefined, {minimumFractionDigits: 2}); if (document.getElementById('24h-vol')) document.getElementById('24h-vol').innerText = (Math.random() * 500 + 100).toFixed(2) + 'M'; if (document.getElementById('price-fiat')) document.getElementById('price-fiat').innerText = '≈ ¥' + (coin.price * 7.15).toLocaleString(undefined, {minimumFractionDigits: 2}); } // Update order book simulation simulateOrderBook(); } function simulateOrderBook() { const symbol = document.getElementById('current-symbol')?.value; if (!symbol || !currentMarketData[symbol]) return; const basePrice = currentMarketData[symbol].price; const askContainer = document.getElementById('order-book-asks'); const bidContainer = document.getElementById('order-book-bids'); if (!askContainer || !bidContainer) return; let askHtml = ''; let bidHtml = ''; // Asks (Red) for (let i = 5; i > 0; i--) { const price = basePrice * (1 + (i * 0.0002)); const amount = Math.random() * 2 + 0.1; const depth = Math.random() * 80 + 10; askHtml += `
${price.toFixed(2)} ${amount.toFixed(4)}
`; } // Bids (Green) for (let i = 1; i <= 5; i++) { const price = basePrice * (1 - (i * 0.0002)); const amount = Math.random() * 2 + 0.1; const depth = Math.random() * 80 + 10; bidHtml += `
${price.toFixed(2)} ${amount.toFixed(4)}
`; } askContainer.innerHTML = askHtml; bidContainer.innerHTML = bidHtml; } // Initialization document.addEventListener('DOMContentLoaded', () => { fetchMarketData(); setInterval(fetchMarketData, 3000); // Search listener const searchInput = document.getElementById('market-search'); if (searchInput) { searchInput.addEventListener('input', updateUI); } });