测试
This commit is contained in:
parent
3e2db33621
commit
00bab18fd4
@ -256,23 +256,28 @@ $requests = $stmt->fetchAll();
|
||||
<span class="badge bg-light text-muted border"><?= $r['status'] == '4' ? '已拒绝' : '已通过' ?></span>
|
||||
<?php else: ?>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<?php if ($r['status'] === '0' || $r['status'] === 'pending'): ?>
|
||||
<button type="button" class="btn btn-primary" onclick="submitMatchOnly(<?= $r['id'] ?>)">
|
||||
匹配成功
|
||||
</button>
|
||||
<?php elseif ($r['status'] === '1' || $r['status'] === 'matched'): ?>
|
||||
<button type="button" class="btn btn-info text-white" onclick="showSendModal(<?= $r['id'] ?>, '<?= htmlspecialchars($r['account_bank'] ?? '') ?>', '<?= htmlspecialchars($r['account_name'] ?? '') ?>', '<?= htmlspecialchars($r['account_number'] ?? '') ?>')">
|
||||
发送账户
|
||||
</button>
|
||||
<?php elseif ($r['status'] === '2' || $r['status'] === 'account_sent'): ?>
|
||||
<span class="badge bg-light text-muted border d-flex align-items-center px-2">等待用户转账...</span>
|
||||
<?php elseif ($r['status'] === 'finished'): ?>
|
||||
<?php if ($r['type'] === 'recharge'): ?>
|
||||
<?php if ($r['type'] === 'recharge'): ?>
|
||||
<?php if ($r['status'] == '0' || $r['status'] == 'pending'): ?>
|
||||
<button type="button" class="btn btn-primary" onclick="submitMatchOnly(<?= $r['id'] ?>)">
|
||||
匹配成功
|
||||
</button>
|
||||
<?php elseif ($r['status'] == '1' || $r['status'] == 'matched'): ?>
|
||||
<button type="button" class="btn btn-info text-white" onclick="showSendModal(<?= $r['id'] ?>, '<?= htmlspecialchars($r['account_bank'] ?? '') ?>', '<?= htmlspecialchars($r['account_name'] ?? '') ?>', '<?= htmlspecialchars($r['account_number'] ?? '') ?>')">
|
||||
发送账户
|
||||
</button>
|
||||
<?php elseif ($r['status'] == '2' || $r['status'] == 'account_sent'): ?>
|
||||
<span class="badge bg-light text-muted border d-flex align-items-center px-2">等待用户转账...</span>
|
||||
<?php elseif ($r['status'] == 'finished'): ?>
|
||||
<button type="button" class="btn btn-outline-success fw-bold"
|
||||
onclick="showApproveModal(<?= $r['id'] ?>, <?= $r['fiat_amount'] ?: 0 ?>, '<?= $r['fiat_currency'] ?: 'USDT' ?>', <?= $display_amount ?>)">
|
||||
通过
|
||||
</button>
|
||||
<button class="btn btn-outline-danger fw-bold ms-1" onclick="showRejectModal(<?= $r['id'] ?>)">拒绝</button>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-light text-muted border"><?= htmlspecialchars($r['status']) ?></span>
|
||||
<?php endif; ?>
|
||||
<?php else: /* Withdrawal */ ?>
|
||||
<?php if ($r['status'] == '0' || $r['status'] == 'pending' || $r['status'] == 'finished'): ?>
|
||||
<form method="POST" class="d-inline">
|
||||
<input type="hidden" name="request_id" value="<?= $r['id'] ?>">
|
||||
<input type="hidden" name="action" value="approve">
|
||||
@ -280,10 +285,10 @@ $requests = $stmt->fetchAll();
|
||||
通过
|
||||
</button>
|
||||
</form>
|
||||
<button class="btn btn-outline-danger fw-bold ms-1" onclick="showRejectModal(<?= $r['id'] ?>)">拒绝</button>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-light text-muted border"><?= htmlspecialchars($r['status']) ?></span>
|
||||
<?php endif; ?>
|
||||
<button class="btn btn-outline-danger fw-bold ms-1" onclick="showRejectModal(<?= $r['id'] ?>)">拒绝</button>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-light text-muted border"><?= htmlspecialchars($r['status']) ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
60
recharge.php
60
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 = `
|
||||
<div class="text-center text-lg-start position-relative" style="z-index: 2;">
|
||||
@ -744,7 +736,6 @@ function renderRechargeUI(data) {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// 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) {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user