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();
= $r['status'] == '4' ? '已拒绝' : '已通过' ?>
-
-
-
-
-
- 等待用户转账...
-
-
+
+
+
+
+
+
+ 等待用户转账...
+
+
+ = htmlspecialchars($r['status']) ?>
+
+
+
+
+
+ = htmlspecialchars($r['status']) ?>
-
-
- = htmlspecialchars($r['status']) ?>
@@ -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 = '= $trc20_addr ?>';
const userId = '= $user['uid'] ?? $user['id'] ?>';
-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: '= __("confirm") ?>'
- });
-}
-
-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', '= __("recharge_success_title") ?>', '= __("recharge_success_text") ?>');
}
@@ -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) {}