165 lines
6.8 KiB
JavaScript
165 lines
6.8 KiB
JavaScript
// 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 += `
|
|
<div class="crypto-item ${active}" onclick="window.location.href='trade.php?symbol=${symbol}'">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div class="d-flex align-items-center">
|
|
<img src="${coin.icon}" class="crypto-icon">
|
|
<div>
|
|
<div class="fw-bold text-white small">${symbol}</div>
|
|
<div class="text-muted" style="font-size: 0.7rem;">${coin.name}</div>
|
|
</div>
|
|
</div>
|
|
<div class="text-end">
|
|
<div class="text-white small fw-bold">$${coin.price.toLocaleString(undefined, {minimumFractionDigits: 2})}</div>
|
|
<div class="${changeClass}" style="font-size: 0.7rem;">${changeSign}${coin.change.toFixed(2)}%</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
});
|
|
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 += `
|
|
<div class="order-book-row ask" onclick="document.getElementById('order-price').value = ${price.toFixed(2)}">
|
|
<div class="depth-bg ask" style="width: ${depth}%"></div>
|
|
<span class="price">${price.toFixed(2)}</span>
|
|
<span class="amount">${amount.toFixed(4)}</span>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// 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 += `
|
|
<div class="order-book-row bid" onclick="document.getElementById('order-price').value = ${price.toFixed(2)}">
|
|
<div class="depth-bg bid" style="width: ${depth}%"></div>
|
|
<span class="price">${price.toFixed(2)}</span>
|
|
<span class="amount">${amount.toFixed(4)}</span>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}); |