diff --git a/admin/finance.php b/admin/finance.php index 5bd95c8..e043409 100644 --- a/admin/finance.php +++ b/admin/finance.php @@ -256,23 +256,28 @@ $requests = $stmt->fetchAll();
- - - - - - 等待用户转账... - - + + + + + + + 等待用户转账... + + + + + +
@@ -280,10 +285,10 @@ $requests = $stmt->fetchAll(); 通过
+ + + - - -
@@ -404,36 +409,6 @@ async function submitMatchOnly(id) { if(data.success) location.reload(); else alert(data.error || '操作失败'); } -function showSendModal(id, bank, name, account) { - document.getElementById('send_id').value = id; - document.getElementById('send_bank').value = bank; - document.getElementById('send_name').value = name; - document.getElementById('send_account').value = account; - new bootstrap.Modal(document.getElementById('sendModal')).show(); -} - -async function submitSend() { - const id = document.getElementById('send_id').value; - const bank = document.getElementById('send_bank').value; - const name = document.getElementById('send_name').value; - const account = document.getElementById('send_account').value; - const note = document.getElementById('send_note').value; - - if(!bank || !name || !account) return alert('请完整填写信息'); - - const formData = new FormData(); - formData.append('id', id); - formData.append('bank', bank); - formData.append('name', name); - formData.append('account', account); - formData.append('note', note); - - const resp = await fetch('../api/admin_recharge.php?action=send_account', { method: 'POST', body: formData }); - const data = await resp.json(); - if(data.success) location.reload(); else alert(data.error || '操作失败'); -} - - function showSendModal(id, bank, name, account) { document.getElementById('send_id').value = id; document.getElementById('send_bank').value = bank; diff --git a/db/config.php b/db/config.php index c0d1cb2..89e1419 100644 --- a/db/config.php +++ b/db/config.php @@ -81,6 +81,11 @@ function ensureSchema() { foreach ($columns as $c) { if ($c['Field'] === 'status' && strpos(strtolower($c['Type']), 'int') !== false) { $db->exec("ALTER TABLE finance_requests MODIFY COLUMN status VARCHAR(50) DEFAULT '0'"); + // Fix legacy data + $db->exec("UPDATE finance_requests SET status = '0' WHERE status = '0' OR status = 0"); + $db->exec("UPDATE finance_requests SET status = '1' WHERE status = '1' OR status = 1"); + $db->exec("UPDATE finance_requests SET status = '2' WHERE status = '2' OR status = 2"); + $db->exec("UPDATE finance_requests SET status = '3' WHERE status = '3' OR status = 3"); } } diff --git a/recharge.php b/recharge.php index c0f83ee..e349e34 100644 --- a/recharge.php +++ b/recharge.php @@ -405,32 +405,17 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc let currentNetwork = 'TRC20'; let currentAddress = ''; const userId = ''; -const apiPath = (window.location.origin + window.location.pathname).split('/recharge.php')[0] + '/api/'; +const apiPath = 'api/'; let rechargeCountdownInterval; let modalChatLastIds = new Set(); let remainingSeconds = 1800; let modalChatPolling = false; -window.lastRechargeStatus = null; // Track status to prevent flickering - -function notify(icon, title, text = '') { - return Swal.fire({ - icon: icon, - title: title, - text: text, - background: '#1e2329', - color: '#fff', - confirmButtonColor: '#0062ff', - confirmButtonText: '' - }); -} - -let exchangeRates = {}; +window.lastRechargeStatus = null; async function updateRate() { const select = document.getElementById('fiatCurrency'); const symbol = select.value; - // Try to get fresh rates try { const resp = await fetch(apiPath + 'exchange.php?v=' + Date.now()); const data = await resp.json(); @@ -446,7 +431,6 @@ async function updateRate() { document.getElementById('selectedCurrencyLabel').innerText = symbol; document.getElementById('currentRateText').innerText = `${rate.toFixed(4)} ${symbol}`; - // Update the data-rate attribute so calculateUSDT can use it too select.options[select.selectedIndex].setAttribute('data-rate', rate); calculateUSDT(); @@ -455,6 +439,7 @@ async function updateRate() { function calculateUSDT() { const amount = parseFloat(document.getElementById('fiatAmount').value) || 0; const select = document.getElementById('fiatCurrency'); + if (!select) return; const rate = parseFloat(select.options[select.selectedIndex].getAttribute('data-rate')); const est = amount / rate; document.getElementById('estUsdt').innerText = est.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' USDT'; @@ -473,8 +458,10 @@ function selectNetwork(net, addr) { btn.classList.add('btn-outline-secondary'); } }); - document.getElementById('cryptoAddress').value = addr; - document.getElementById('qrCode').src = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${addr}`; + const addrInput = document.getElementById('cryptoAddress'); + if (addrInput) addrInput.value = addr; + const qrImg = document.getElementById('qrCode'); + if (qrImg) qrImg.src = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${addr}`; } function saveRechargeState(state) { @@ -489,6 +476,7 @@ function clearRechargeState() { localStorage.removeItem('recharge_state'); if (rechargeCountdownInterval) clearInterval(rechargeCountdownInterval); if (window.statusPollingInterval) clearInterval(window.statusPollingInterval); + window.lastRechargeStatus = null; } function finishTransfer() { @@ -500,7 +488,12 @@ function finishTransfer() { formData.append('order_id', orderId); fetch(apiPath + 'finance.php?v=' + Date.now(), { method: 'POST', body: formData }) .then(r => r.json()) - .then(data => { if (data.success) renderRechargeUI({status: 'finished'}); }); + .then(data => { + if (data.success) { + window.lastRechargeStatus = 'finished'; + renderRechargeUI({status: 'finished'}); + } + }); } else { notify('warning', '订单信息丢失,请刷新页面'); } @@ -509,8 +502,10 @@ function finishTransfer() { function finishTransferUI() { clearRechargeState(); const modalEl = document.getElementById('rechargeModal'); - const modalInstance = bootstrap.Modal.getInstance(modalEl); - if (modalInstance) modalInstance.hide(); + if (modalEl) { + const modalInstance = bootstrap.Modal.getInstance(modalEl); + if (modalInstance) modalInstance.hide(); + } notify('success', '', ''); } @@ -525,7 +520,7 @@ function openRechargeModal(initialMessage, isRestore = false, orderId = null) { if (!isRestore) { remainingSeconds = 1800; saveRechargeState({ phase: 'pending', initialMessage, orderId: currentOrderId }); - sendModalMessage(initialMessage); // Automatically notify admin about the new recharge request + sendModalMessage(initialMessage); } if (currentOrderId) startStatusPolling(currentOrderId); @@ -544,7 +539,7 @@ function openRechargeModal(initialMessage, isRestore = false, orderId = null) { if (--remainingSeconds < 0) clearInterval(rechargeCountdownInterval); }, 1000); - if (!isRestore) renderRechargeUI({ status: 'pending' }); + if (!isRestore) renderRechargeUI({ status: '0' }); initModalChat(); } @@ -554,14 +549,12 @@ function startStatusPolling(order_id) { const modalEl = document.getElementById('rechargeModal'); if (!modalEl || !modalEl.classList.contains('show')) return; try { - // Add cache busting const r = await fetch(apiPath + `recharge_status.php?id=${order_id}&t=${Date.now()}`); + if (!r.ok) throw new Error('Network response was not ok'); const data = await r.json(); if (data.success) { - // Force status to string const currentStatus = String(data.status); - // Only re-render if status has changed or UI is empty const side = document.querySelector('.info-side'); if (window.lastRechargeStatus !== currentStatus || (side && side.innerHTML.trim() === "")) { window.lastRechargeStatus = currentStatus; @@ -572,7 +565,9 @@ function startStatusPolling(order_id) { clearInterval(window.statusPollingInterval); } } - } catch (e) { console.error('Status polling error:', e); } + } catch (e) { + console.error('Status polling error:', e); + } }; checkStatus(); window.statusPollingInterval = setInterval(checkStatus, 3000); @@ -582,10 +577,8 @@ function renderRechargeUI(data) { const side = document.querySelector('.info-side'); if (!side) return; - // Normalize status to string const status = String(data.status || '0'); - // Check if approved or rejected if (status === 'completed' || status === '3') { finishTransferUI(); return; @@ -613,7 +606,6 @@ function renderRechargeUI(data) { return; } - // Workflow phases if (status === 'pending' || status === '0') { side.innerHTML = `
@@ -744,7 +736,6 @@ function renderRechargeUI(data) {
`; } - // Sync countdown if exists if (remainingSeconds > 0) { let mins = Math.floor(remainingSeconds / 60), secs = remainingSeconds % 60; const timeStr = `${mins}:${secs < 10 ? '0' : ''}${secs}`; @@ -762,9 +753,10 @@ document.addEventListener('DOMContentLoaded', async () => { if (remainingSeconds > 0 && state.orderId) { openRechargeModal(state.initialMessage, true, state.orderId); try { - const r = await fetch(`api/recharge_status.php?id=${state.orderId}&_t=${Date.now()}`); + const r = await fetch(apiPath + `recharge_status.php?id=${state.orderId}&_t=${Date.now()}`); const data = await r.json(); if (data.success) { + window.lastRechargeStatus = String(data.status); renderRechargeUI(data); } } catch (e) {}