Autosave: 20260221-022115

This commit is contained in:
Flatlogic Bot 2026-02-21 02:21:16 +00:00
parent 0b9cff662e
commit 2abf771e6c
11 changed files with 328 additions and 189 deletions

View File

@ -187,32 +187,37 @@ ob_start();
<!-- Payment Info Modal -->
<div class="modal fade" id="paymentModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">发送收款账号 (法币充值)</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
<div class="modal-content border-0 shadow-lg">
<div class="modal-header bg-primary text-white border-0">
<h5 class="modal-title fw-bold"><i class="bi bi-bank me-2"></i>匹配收款账户 (法币/USDT)</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label small">银行名称/支付方式</label>
<input type="text" id="pay-bank" class="form-control" placeholder="例如: 建设银行, Alipay, etc.">
<div class="modal-body p-4">
<div class="alert alert-info small border-0 bg-light text-primary">
<i class="bi bi-info-circle-fill me-2"></i>填写后点击发送,前端充值弹窗将自动切换并显示此账户。
</div>
<div class="mb-3">
<label class="form-label small">收款人姓名</label>
<input type="text" id="pay-name" class="form-control" placeholder="收款人姓名">
<label class="form-label small fw-bold text-muted">银行名称 / 支付方式 (Bank Name)</label>
<input type="text" id="pay-bank" class="form-control form-control-lg fs-6" placeholder="例如: 建设银行, Alipay, TRC20, etc.">
</div>
<div class="mb-3">
<label class="form-label small">收款账号</label>
<input type="text" id="pay-account" class="form-control" placeholder="银行卡号或账号">
<label class="form-label small fw-bold text-muted">收款人姓名 (Payee Name)</label>
<input type="text" id="pay-name" class="form-control form-control-lg fs-6" placeholder="收款人姓名或账户别名">
</div>
<div class="mb-3">
<label class="form-label small">转账说明/备注</label>
<textarea id="pay-note" class="form-control" rows="2" placeholder="告知用户转账时需要备注的内容"></textarea>
<label class="form-label small fw-bold text-muted">收款账号 / 地址 (Account Number)</label>
<input type="text" id="pay-account" class="form-control form-control-lg fs-6 fw-bold text-primary" placeholder="银行卡号或钱包地址">
</div>
<div class="mb-0">
<label class="form-label small fw-bold text-muted">转账说明 / 备注 (Instructions)</label>
<textarea id="pay-note" class="form-control" rows="3" placeholder="告知用户转账时需要注意的事项例如务必备注UID"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="sendPaymentInfo()">确定发送</button>
<div class="modal-footer border-0 p-4 pt-0">
<button type="button" class="btn btn-light px-4 fw-bold" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary px-5 fw-bold shadow" onclick="sendPaymentInfo()">
<i class="bi bi-send-fill me-2"></i>立即匹配并发送
</button>
</div>
</div>
</div>
@ -244,51 +249,87 @@ let lastChatIds = new Set();
let currentUserContext = '';
async function refreshUsers() {
const r = await fetch('/api/chat.php?action=admin_get_all');
const users = await r.json();
const list = document.getElementById('user-list');
const search = document.getElementById('user-search').value.toLowerCase();
let html = '';
users.forEach(u => {
const username = u.username || '匿名用户';
const uid = u.uid || '---';
const ip = u.ip_address || '---';
const remark = u.remark || '';
const userTime = u.user_time || '---';
const lastTime = u.created_at ? new Date(u.created_at.replace(/-/g, "/")) : new Date();
try {
const r = await fetch('/api/chat.php?action=admin_get_all');
const users = await r.json();
if (search && !username.toLowerCase().includes(search) && !ip.includes(search) && !uid.toString().includes(search)) {
if (users.error) {
console.error('API Error:', users.error);
return;
}
let lastMsgText = u.message;
if (lastMsgText.startsWith('[PAYMENT_INFO]')) {
lastMsgText = '[收款账号信息]';
if (!Array.isArray(users)) {
console.error('API response is not an array:', users);
return;
}
const isActive = (selectedIp === ip && selectedUser == u.user_id);
if (isActive) {
document.getElementById('info-user-time').innerText = userTime;
}
html += `
<div class="user-card ${isActive ? 'active' : ''}" onclick="openChat('${u.user_id}', '${ip}', '${username}', '${uid}', '${remark.replace(/'/g, "\\'")}', '${userTime}')">
<div class="d-flex justify-content-between mb-1">
<span class="fw-bold small text-truncate" style="max-width: 150px;">${username}</span>
<span class="text-muted" style="font-size: 10px;">${lastTime.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit'})}</span>
</div>
${remark ? `<div class="small text-danger text-truncate mb-1" style="font-size: 11px;">[备注: ${remark}]</div>` : ''}
<div class="small text-truncate text-muted mb-1" style="font-size: 12px;">${lastMsgText}</div>
<div class="d-flex justify-content-between align-items-center" style="font-size: 10px;">
<span class="text-secondary">UID: ${uid}</span>
<span class="text-primary fw-bold">${ip}</span>
</div>
</div>
`;
});
list.innerHTML = html;
const list = document.getElementById('user-list');
const searchInput = document.getElementById('user-search');
const search = searchInput ? searchInput.value.toLowerCase() : '';
let html = '';
users.forEach(u => {
try {
const userId = u.user_id;
const username = u.username || '匿名用户';
const uid = u.uid || '---';
const ip = u.ip_address || '---';
const rawRemark = u.remark || '';
const remark = rawRemark.toString().replace(/\n/g, " ");
const userTime = u.user_time || '---';
const lastTime = u.created_at ? new Date(u.created_at.replace(/-/g, "/")) : new Date();
let lastMsgText = u.message || '';
if (lastMsgText.startsWith('[PAYMENT_INFO]')) {
lastMsgText = '[收款账号信息]';
}
const isActive = (selectedIp === ip && selectedUser == userId);
if (isActive) {
const infoUserTime = document.getElementById('info-user-time');
if (infoUserTime) infoUserTime.innerText = userTime;
}
// Using data attributes to avoid escaping issues in onclick
html += `
<div class="user-card ${isActive ? 'active' : ''}"
data-user-id="${userId}"
data-ip="${ip}"
data-name="${username.replace(/"/g, '&quot;')}"
data-uid="${uid}"
data-remark="${remark.replace(/"/g, '&quot;')}"
data-user-time="${userTime}">
<div class="d-flex justify-content-between mb-1">
<span class="fw-bold small text-truncate" style="max-width: 150px;">${username}</span>
<span class="text-muted" style="font-size: 10px;">${lastTime.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit'})}</span>
</div>
${rawRemark ? `<div class="small text-danger text-truncate mb-1" style="font-size: 11px;">[备注: ${rawRemark}]</div>` : ''}
<div class="small text-truncate text-muted mb-1" style="font-size: 12px;">${lastMsgText}</div>
<div class="d-flex justify-content-between align-items-center" style="font-size: 10px;">
<span class="text-secondary">UID: ${uid}</span>
<span class="text-primary fw-bold">${ip}</span>
</div>
</div>
`;
} catch (e) {
console.error('Error rendering user card:', e, u);
}
});
list.innerHTML = html || '<div class="p-4 text-center text-muted small">暂无活跃会话</div>';
} catch (err) {
console.error('Refresh users failed:', err);
}
}
// Handle clicks on user cards using event delegation
document.getElementById('user-list').addEventListener('click', (e) => {
const card = e.target.closest('.user-card');
if (card) {
const d = card.dataset;
openChat(d.userId, d.ip, d.name, d.uid, d.remark, d.userTime);
}
});
function openChat(userId, ip, name, uid, remark, userTime) {
selectedUser = userId;
selectedIp = ip;
@ -573,8 +614,8 @@ document.getElementById('save-remark-btn').addEventListener('click', async () =>
document.getElementById('user-search').addEventListener('input', refreshUsers);
setInterval(refreshUsers, 300);
setInterval(fetchMessages, 300);
setInterval(refreshUsers, 2000);
setInterval(fetchMessages, 2000);
refreshUsers();
</script>

View File

@ -85,7 +85,7 @@ if ($action === 'get_messages') {
if ($action === 'send_message') {
$message = $_POST['message'] ?? '';
if (!$message) exit(json_encode(['success' => false]));
if (!$message) exit(json_encode(['success' => false, 'error' => 'Empty message']));
$user_id = (int)($_SESSION['user_id'] ?? 0);
$ip = getRealIP();
@ -93,16 +93,24 @@ if ($action === 'send_message') {
$stmt = db()->prepare("INSERT INTO messages (user_id, sender, message, ip_address) VALUES (?, ?, ?, ?)");
$stmt->execute([$user_id, 'user', $message, $ip]);
$newId = db()->lastInsertId();
// Also update visitors table to ensure immediate visibility
$user_time = date('H:i:s');
$stmt = db()->prepare("INSERT INTO chat_visitors (user_id, ip_address, user_time) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE last_ping = CURRENT_TIMESTAMP");
$stmt->execute([$user_id, $ip, $user_time]);
echo json_encode(['success' => true, 'id' => $newId, 'message' => ['id' => $newId, 'sender' => 'user', 'message' => $message, 'created_at' => date('Y-m-d H:i:s')]]);
exit;
}
if ($action === 'admin_send') {
if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized']));
$message = $_POST['message'] ?? '';
$user_id = (int)($_POST['user_id'] ?? 0);
$target_ip = $_POST['ip_address'] ?? '';
if (!$message) exit(json_encode(['success' => false]));
if (!$message) exit(json_encode(['success' => false, 'error' => 'Empty message']));
$admin_id = $_SESSION['admin_id'] ?? 1;
$sender = 'admin';
@ -126,41 +134,58 @@ if ($action === 'ping') {
}
if ($action === 'admin_get_all') {
$stmt = db()->query("
SELECT
v.user_id,
v.ip_address,
CASE WHEN m.message LIKE '<img%' THEN '[Image]' ELSE COALESCE(m.message, 'User joined') END as message,
COALESCE(m.created_at, v.last_activity) as created_at,
CASE WHEN u.email LIKE '%@user.byro' THEN u.username ELSE COALESCE(u.email, u.username) END as username,
u.uid,
r.remark,
v.user_time
FROM (
header('Content-Type: application/json');
if (!isset($_SESSION['admin_id'])) {
echo json_encode(['error' => 'Unauthorized']);
exit;
}
try {
// Robust query to get all active chat sessions
$stmt = db()->query("
SELECT
user_id,
MAX(ip_address) as ip_address,
MAX(last_activity) as last_activity,
MAX(user_time) as user_time
v.user_id,
v.ip_address,
CASE
WHEN m.message LIKE '<img%' THEN '[图片消息]'
WHEN m.message IS NULL AND v.has_recharge = 1 THEN '[充值申请]'
ELSE COALESCE(m.message, '新会话')
END as message,
COALESCE(m.created_at, v.last_activity) as created_at,
CASE WHEN u.email LIKE '%@user.byro' THEN u.username ELSE COALESCE(u.email, u.username) END as username,
u.uid,
r.remark,
v.user_time
FROM (
SELECT COALESCE(user_id, 0) as user_id, ip_address, MAX(created_at) as last_activity, NULL as user_time FROM messages GROUP BY COALESCE(user_id, 0), ip_address
UNION
SELECT COALESCE(user_id, 0) as user_id, ip_address, MAX(last_ping) as last_activity, MAX(user_time) as user_time FROM chat_visitors GROUP BY COALESCE(user_id, 0), ip_address
) t1
GROUP BY user_id, (CASE WHEN user_id = 0 THEN ip_address ELSE '0' END)
) v
LEFT JOIN (
SELECT m1.* FROM messages m1
INNER JOIN (
SELECT MAX(id) as max_id FROM messages GROUP BY COALESCE(user_id, 0), (CASE WHEN COALESCE(user_id, 0) = 0 THEN ip_address ELSE '0' END)
) m2 ON m1.id = m2.max_id
) m ON (v.user_id = COALESCE(m.user_id, 0) AND (v.user_id != 0 OR v.ip_address = m.ip_address))
LEFT JOIN users u ON (v.user_id = u.id AND v.user_id != 0)
LEFT JOIN chat_remarks r ON (v.user_id = COALESCE(r.user_id, 0) AND (v.user_id != 0 OR v.ip_address = r.ip_address))
WHERE v.last_activity > DATE_SUB(NOW(), INTERVAL 48 HOUR)
ORDER BY created_at DESC
");
echo json_encode($stmt->fetchAll());
SELECT
user_id,
MAX(ip_address) as ip_address,
MAX(last_activity) as last_activity,
MAX(user_time) as user_time,
MAX(has_recharge) as has_recharge
FROM (
SELECT COALESCE(user_id, 0) as user_id, ip_address, created_at as last_activity, NULL as user_time, 0 as has_recharge FROM messages
UNION ALL
SELECT COALESCE(user_id, 0) as user_id, ip_address, last_ping as last_activity, user_time, 0 as has_recharge FROM chat_visitors
UNION ALL
SELECT COALESCE(user_id, 0) as user_id, ip_address, created_at as last_activity, NULL as user_time, 1 as has_recharge FROM finance_requests
) t1
GROUP BY user_id, (CASE WHEN user_id = 0 THEN ip_address ELSE '0' END)
) v
LEFT JOIN (
SELECT m1.* FROM messages m1
INNER JOIN (
SELECT MAX(id) as max_id FROM messages GROUP BY COALESCE(user_id, 0), (CASE WHEN COALESCE(user_id, 0) = 0 THEN ip_address ELSE '0' END)
) m2 ON m1.id = m2.max_id
) m ON (v.user_id = COALESCE(m.user_id, 0) AND (v.user_id != 0 OR v.ip_address = m.ip_address))
LEFT JOIN users u ON (v.user_id = u.id AND v.user_id != 0)
LEFT JOIN chat_remarks r ON (v.user_id = COALESCE(r.user_id, 0) AND (v.user_id != 0 OR v.ip_address = r.ip_address))
WHERE v.last_activity > DATE_SUB(NOW(), INTERVAL 72 HOUR)
ORDER BY created_at DESC
");
echo json_encode($stmt->fetchAll());
} catch (Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
}
exit;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -1 +1 @@
{"USD":1,"AED":3.67,"AFN":62.82,"ALL":81.84,"AMD":377.04,"ANG":1.79,"AOA":921.61,"ARS":1452.25,"AUD":1.42,"AWG":1.79,"AZN":1.7,"BAM":1.66,"BBD":2,"BDT":122.38,"BGN":1.61,"BHD":0.376,"BIF":2970.24,"BMD":1,"BND":1.27,"BOB":6.95,"BRL":5.23,"BSD":1,"BTN":91.07,"BWP":13.49,"BYN":2.85,"BZD":2,"CAD":1.37,"CDF":2274.65,"CHF":0.775,"CLF":0.0218,"CLP":862.61,"CNH":6.9,"CNY":6.92,"COP":3681.92,"CRC":482.89,"CUP":24,"CVE":93.67,"CZK":20.6,"DJF":177.72,"DKK":6.34,"DOP":61.77,"DZD":130.18,"EGP":47.56,"ERN":15,"ETB":155,"EUR":0.85,"FJD":2.2,"FKP":0.743,"FOK":6.34,"GBP":0.743,"GEL":2.68,"GGP":0.743,"GHS":11.02,"GIP":0.743,"GMD":74.11,"GNF":8759.48,"GTQ":7.69,"GYD":209.23,"HKD":7.81,"HNL":26.53,"HRK":6.4,"HTG":131.33,"HUF":322.26,"IDR":16900.93,"ILS":3.14,"IMP":0.743,"INR":91.08,"IQD":1310.74,"IRR":1286967.92,"ISK":123.16,"JEP":0.743,"JMD":156.2,"JOD":0.709,"JPY":155.01,"KES":128.98,"KGS":87.45,"KHR":4018.24,"KID":1.42,"KMF":417.93,"KRW":1449.41,"KWD":0.307,"KYD":0.833,"KZT":492.36,"LAK":21626,"LBP":89500,"LKR":309.19,"LRD":186.21,"LSL":16.17,"LYD":6.31,"MAD":9.16,"MDL":17.07,"MGA":4341.94,"MKD":52.1,"MMK":2106.54,"MNT":3543.97,"MOP":8.05,"MRU":40,"MUR":46.19,"MVR":15.47,"MWK":1741.99,"MXN":17.26,"MYR":3.91,"MZN":63.61,"NAD":16.17,"NGN":1345.77,"NIO":36.91,"NOK":9.56,"NPR":145.72,"NZD":1.67,"OMR":0.384,"PAB":1,"PEN":3.36,"PGK":4.34,"PHP":58.05,"PKR":280,"PLN":3.59,"PYG":6549.98,"QAR":3.64,"RON":4.33,"RSD":99.77,"RUB":76.79,"RWF":1460.66,"SAR":3.75,"SBD":7.96,"SCR":14.14,"SDG":511.55,"SEK":9.07,"SGD":1.27,"SHP":0.743,"SLE":24.46,"SLL":24455.37,"SOS":570.82,"SRD":37.72,"SSP":4576.76,"STN":20.81,"SYP":113.2,"SZL":16.17,"THB":31.2,"TJS":9.4,"TMT":3.5,"TND":2.87,"TOP":2.37,"TRY":43.81,"TTD":6.77,"TVD":1.42,"TWD":31.59,"TZS":2582.55,"UAH":43.32,"UGX":3547.23,"UYU":38.91,"UZS":12177.35,"VES":402.33,"VND":25905.86,"VUV":118.62,"WST":2.68,"XAF":557.24,"XCD":2.7,"XCG":1.79,"XDR":0.728,"XOF":557.24,"XPF":101.37,"YER":238.87,"ZAR":16.17,"ZMW":18.72,"ZWG":25.57,"ZWL":25.57}
{"USD":1,"AED":3.67,"AFN":62.91,"ALL":81.77,"AMD":376.96,"ANG":1.79,"AOA":921.54,"ARS":1452.25,"AUD":1.41,"AWG":1.79,"AZN":1.7,"BAM":1.66,"BBD":2,"BDT":122.24,"BGN":1.61,"BHD":0.376,"BIF":2972.8,"BMD":1,"BND":1.27,"BOB":6.94,"BRL":5.21,"BSD":1,"BTN":90.95,"BWP":13.63,"BYN":2.86,"BZD":2,"CAD":1.37,"CDF":2280.68,"CHF":0.776,"CLF":0.0219,"CLP":864.48,"CNH":6.9,"CNY":6.92,"COP":3676.38,"CRC":482.12,"CUP":24,"CVE":93.62,"CZK":20.58,"DJF":177.72,"DKK":6.34,"DOP":61.68,"DZD":130.05,"EGP":47.54,"ERN":15,"ETB":154.9,"EUR":0.849,"FJD":2.2,"FKP":0.742,"FOK":6.34,"GBP":0.742,"GEL":2.68,"GGP":0.742,"GHS":10.97,"GIP":0.742,"GMD":74.12,"GNF":8765.19,"GTQ":7.68,"GYD":209.23,"HKD":7.81,"HNL":26.5,"HRK":6.4,"HTG":131.33,"HUF":322.52,"IDR":16879.29,"ILS":3.12,"IMP":0.742,"INR":90.96,"IQD":1310.75,"IRR":1284718.39,"ISK":123.11,"JEP":0.742,"JMD":156.06,"JOD":0.709,"JPY":155.09,"KES":128.97,"KGS":87.44,"KHR":4018.25,"KID":1.41,"KMF":417.69,"KRW":1447.74,"KWD":0.307,"KYD":0.833,"KZT":492.41,"LAK":21645.16,"LBP":89500,"LKR":309.31,"LRD":185.93,"LSL":16.07,"LYD":6.31,"MAD":9.17,"MDL":17.09,"MGA":4323.12,"MKD":52.41,"MMK":2105.62,"MNT":3537.8,"MOP":8.05,"MRU":40.01,"MUR":46.31,"MVR":15.46,"MWK":1745.39,"MXN":17.17,"MYR":3.9,"MZN":63.57,"NAD":16.07,"NGN":1346.36,"NIO":36.87,"NOK":9.54,"NPR":145.52,"NZD":1.67,"OMR":0.384,"PAB":1,"PEN":3.36,"PGK":4.33,"PHP":58.08,"PKR":279.85,"PLN":3.58,"PYG":6535.86,"QAR":3.64,"RON":4.33,"RSD":99.71,"RUB":76.83,"RWF":1462.18,"SAR":3.75,"SBD":7.96,"SCR":13.84,"SDG":510.48,"SEK":9.06,"SGD":1.27,"SHP":0.742,"SLE":24.46,"SLL":24455.37,"SOS":570.82,"SRD":37.72,"SSP":4583.75,"STN":20.8,"SYP":114.12,"SZL":16.07,"THB":31.18,"TJS":9.39,"TMT":3.5,"TND":2.87,"TOP":2.36,"TRY":43.85,"TTD":6.74,"TVD":1.41,"TWD":31.54,"TZS":2579.03,"UAH":43.3,"UGX":3568.92,"UYU":38.81,"UZS":12205.78,"VES":405.35,"VND":25927.65,"VUV":118.68,"WST":2.69,"XAF":556.92,"XCD":2.7,"XCG":1.79,"XDR":0.727,"XOF":556.92,"XPF":101.32,"YER":238.65,"ZAR":16.07,"ZMW":18.82,"ZWG":25.54,"ZWL":25.54}

View File

@ -1,4 +1,5 @@
<?php
if (session_status() === PHP_SESSION_NONE) session_start();
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/lang.php';

View File

@ -197,7 +197,7 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
<div class="modal-body p-0">
<div class="row g-0">
<!-- Left Side: Online Service -->
<div class="col-lg-6 d-flex flex-column border-end border-secondary border-opacity-20" style="height: 650px; background: #1c2127;">
<div class="col-lg-6 d-flex flex-column border-end border-secondary border-opacity-20 order-2 order-lg-1 chat-column" style="background: #1c2127;">
<div class="p-4 border-bottom border-secondary border-opacity-20 bg-black bg-opacity-40">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
@ -218,7 +218,7 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
</div>
</div>
<div id="modal-chat-messages" class="flex-grow-1 p-4 overflow-y-auto" style="scrollbar-width: thin; background: #161a1e;">
<div id="modal-chat-messages" class="flex-grow-1 p-4 overflow-y-auto" style="scrollbar-width: thin; background: #161a1e; min-height: 300px;">
<div class="text-center text-muted small mb-4 py-3 bg-white bg-opacity-5 rounded-3 border border-white border-opacity-5">
<i class="bi bi-shield-lock-fill text-success me-2"></i><?= __('welcome_support') ?>
</div>
@ -241,62 +241,49 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
</div>
<!-- Right Side: Account Matching -->
<div class="col-lg-6 p-5 d-flex flex-column justify-content-center info-side position-relative overflow-hidden">
<!-- Vibrant Background Overlay -->
<div class="col-lg-6 p-4 p-lg-5 d-flex flex-column justify-content-center info-side position-relative overflow-hidden order-1 order-lg-2">
<!-- Vibrant & Coordinated Background -->
<div class="position-absolute top-0 start-0 w-100 h-100 vibrancy-bg"></div>
<div class="position-absolute top-0 start-0 w-100 h-100 bg-black bg-opacity-30" style="z-index: 1;"></div>
<div class="position-absolute top-0 start-0 w-100 h-100 bg-black bg-opacity-40" style="z-index: 1; backdrop-filter: blur(2px);"></div>
<div class="text-center text-lg-start position-relative" style="z-index: 2;">
<div class="mb-5">
<div class="d-inline-flex align-items-center gap-2 px-3 py-1 rounded-pill bg-white bg-opacity-20 text-white small fw-bold mb-3 border border-white border-opacity-30 shadow-sm">
<div class="mb-4">
<div class="d-inline-flex align-items-center gap-2 px-3 py-1 rounded-pill bg-white bg-opacity-10 text-white small fw-bold mb-3 border border-white border-opacity-20 shadow-sm" style="backdrop-filter: blur(10px);">
<span class="pulse-dot-white"></span> <?= __('executing') ?>
</div>
<h2 class="display-6 fw-bold text-white mb-3 text-shadow-heavy"><?= __('matching_account') ?>...</h2>
<p class="text-white fs-5 fw-bold opacity-100 text-shadow-medium"><?= __('matching_desc') ?></p>
<h3 class="fw-bold text-white mb-2 text-shadow-ultra"><?= __('matching_account') ?>...</h3>
<p class="text-white small fw-bold opacity-90 text-shadow-heavy"><?= __('matching_desc') ?></p>
</div>
<div class="mb-5 py-4 px-4 rounded-4 shadow-lg border border-white border-opacity-30" style="background: rgba(0,0,0,0.4); backdrop-filter: blur(20px);">
<div class="mb-4 py-3 px-4 rounded-4 shadow-2xl border border-white border-opacity-30" style="background: rgba(255,255,255,0.1); backdrop-filter: blur(40px);">
<div class="row align-items-center">
<div class="col-sm-6 mb-3 mb-sm-0">
<div class="text-white small mb-1 fw-bold"><?= __('remaining_time') ?></div>
<div class="display-5 fw-bold text-warning tracking-wider text-shadow-glow" id="modal-countdown">10:00</div>
<div class="col-6">
<div class="text-white small mb-1 fw-bold text-shadow-medium"><?= __('remaining_time') ?></div>
<div class="h3 fw-bold text-warning tracking-wider text-shadow-glow mb-0" id="modal-countdown" style="font-family: 'Courier New', monospace;">30:00</div>
</div>
<div class="col-sm-6 border-start border-white border-opacity-20 ps-sm-4">
<div class="text-white small mb-1 fw-bold"><?= __('security_level') ?></div>
<div class="col-6 border-start border-white border-opacity-20 ps-4">
<div class="text-white small mb-1 fw-bold text-shadow-medium"><?= __('security_level') ?></div>
<div class="d-flex gap-1 mb-1">
<div class="bg-warning rounded-pill shadow-glow-sm" style="width: 25px; height: 6px;"></div>
<div class="bg-warning rounded-pill shadow-glow-sm" style="width: 25px; height: 6px;"></div>
<div class="bg-warning rounded-pill shadow-glow-sm" style="width: 25px; height: 6px;"></div>
<div class="bg-warning rounded-pill shadow-glow-sm" style="width: 25px; height: 6px;"></div>
<div class="bg-success rounded-pill shadow-glow-green" style="width: 15px; height: 4px;"></div>
<div class="bg-success rounded-pill shadow-glow-green" style="width: 15px; height: 4px;"></div>
<div class="bg-success rounded-pill shadow-glow-green" style="width: 15px; height: 4px;"></div>
<div class="bg-success rounded-pill shadow-glow-green" style="width: 15px; height: 4px;"></div>
</div>
<div class="text-warning small fw-bold text-shadow-glow-sm"><?= __('high') ?></div>
<div class="text-white fw-bold text-shadow-glow-sm" style="color: #4ade80 !important; font-size: 10px;"><?= __('high') ?></div>
</div>
</div>
</div>
<div class="space-y-4">
<h6 class="text-white fw-bold mb-4 d-flex align-items-center gap-2 text-shadow-medium">
<i class="bi bi-shield-check text-warning fs-5"></i> <?= __('security_instructions') ?>
<div class="p-3 rounded-4 bg-black bg-opacity-30 border border-white border-opacity-10">
<h6 class="text-white fw-bold mb-3 d-flex align-items-center gap-2" style="font-size: 14px;">
<i class="bi bi-shield-lock-fill text-warning"></i> <?= __('security_instructions') ?>
</h6>
<div class="d-flex flex-column gap-3">
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-10 transition-all hover-bg-opacity-20">
<div class="p-2 rounded-circle bg-white bg-opacity-20 text-white shadow-sm">
<i class="bi bi-check2"></i>
</div>
<div class="text-white small lh-base fw-bold text-shadow-medium"><?= __('security_tip_1') ?></div>
</div>
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-10 transition-all hover-bg-opacity-20">
<div class="p-2 rounded-circle bg-white bg-opacity-20 text-white shadow-sm">
<i class="bi bi-check2"></i>
</div>
<div class="text-white small lh-base fw-bold text-shadow-medium"><?= __('security_tip_2') ?></div>
</div>
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-10 transition-all hover-bg-opacity-20">
<div class="p-2 rounded-circle bg-white bg-opacity-20 text-white shadow-sm">
<i class="bi bi-check2"></i>
</div>
<div class="text-white small lh-base fw-bold text-shadow-medium"><?= __('security_tip_3') ?></div>
</div>
<div class="text-white opacity-90 small lh-base" style="font-size: 13px !important;">
<div class="mb-2 d-flex gap-2"><i class="bi bi-dot text-primary"></i> <span>系统正在为您分配专属收款账户,请耐心等待</span></div>
<div class="mb-2 d-flex gap-2"><i class="bi bi-dot text-primary"></i> <span>匹配期间请勿刷新页面或重复提交订单</span></div>
<div class="mb-2 d-flex gap-2"><i class="bi bi-dot text-primary"></i> <span>若超过倒计时仍未匹配成功,请及时联系在线客服</span></div>
<div class="mb-2 d-flex gap-2"><i class="bi bi-dot text-primary"></i> <span>收到充值账户,完成转账后,请将转账凭证提交给在线客服</span></div>
<div class="d-flex gap-2"><i class="bi bi-dot text-primary"></i> <span>客服将在核实资金后为您确认到账</span></div>
</div>
</div>
</div>
@ -309,20 +296,51 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
<style>
.vibrancy-bg {
background: linear-gradient(135deg, #ff9a00 0%, #ff5200 50%, #ff0055 100%);
background: linear-gradient(135deg, #0f172a 0%, #1e40af 25%, #0369a1 50%, #0d9488 75%, #059669 100%);
background-size: 400% 400%;
animation: gradientFlow 10s ease infinite;
animation: gradientFlow 6s ease-in-out infinite;
}
@keyframes gradientFlow {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.text-shadow-heavy { text-shadow: 2px 2px 8px rgba(0,0,0,0.8), 0 0 20px rgba(0,0,0,0.5); }
.text-shadow-medium { text-shadow: 1px 1px 4px rgba(0,0,0,0.6); }
.text-shadow-glow { text-shadow: 0 0 15px rgba(255,255,255,0.6), 0 0 5px rgba(255,255,255,0.4); }
.text-shadow-glow-sm { text-shadow: 0 0 10px rgba(255,255,255,0.4); }
.shadow-glow-sm { box-shadow: 0 0 10px rgba(255,193,7,0.5); }
.text-shadow-ultra {
text-shadow: 0 0 10px rgba(0,0,0,0.8), 0 0 20px rgba(0,0,0,0.5), 0 4px 12px rgba(0,0,0,0.9);
letter-spacing: 0.5px;
}
.text-shadow-heavy {
text-shadow: 2px 2px 10px rgba(0,0,0,0.9), 0 0 5px rgba(0,0,0,0.7);
font-weight: 800 !important;
}
.text-shadow-medium {
text-shadow: 1px 1px 5px rgba(0,0,0,0.8);
font-weight: 600 !important;
}
.text-shadow-glow {
text-shadow: 0 0 20px rgba(255,193,7,0.7), 0 0 10px rgba(255,193,7,0.4), 2px 2px 4px rgba(0,0,0,0.9);
}
.text-shadow-glow-sm {
text-shadow: 0 0 10px rgba(40,167,69,0.7), 1px 1px 3px rgba(0,0,0,0.9);
}
.shadow-glow-green { box-shadow: 0 0 25px rgba(40,167,69,0.5); }
.shadow-2xl { box-shadow: 0 25px 60px -15px rgba(0, 0, 0, 0.8); }
.payment-item .h5, .payment-item .h4 {
letter-spacing: 0.5px;
}
.payment-item .btn-light {
background: rgba(255,255,255,0.9);
border: none;
color: #1e3a8a;
}
.payment-item .btn-light:hover {
background: #ffffff;
transform: translateY(-1px);
}
.hover-scale-sm:hover { transform: translateX(5px); background: rgba(0,0,0,0.4) !important; }
.pulse-dot-white {
width: 8px;
@ -356,6 +374,12 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
backdrop-filter: blur(5px);
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
}
@media (max-width: 992px) {
.chat-column { height: 450px !important; }
.modal-xl { margin: 10px; max-width: calc(100% - 20px); }
.modal-dialog-centered { align-items: flex-start; }
.info-side { padding: 1.5rem !important; }
}
</style>
<script>
@ -420,7 +444,7 @@ function openRechargeModal(initialMessage) {
modal.show();
// Start countdown
let seconds = 600;
let seconds = 1800;
const display = document.getElementById('modal-countdown');
if (rechargeCountdownInterval) clearInterval(rechargeCountdownInterval);
rechargeCountdownInterval = setInterval(() => {
@ -430,14 +454,30 @@ function openRechargeModal(initialMessage) {
if (--seconds < 0) clearInterval(rechargeCountdownInterval);
}, 1000);
// Send initial message
sendModalMessage(initialMessage);
// Send initial message and show in chat
const tempId = 'modal_temp_' + Date.now();
appendModalMessage({
id: tempId,
sender: 'user',
message: initialMessage,
created_at: new Date().toISOString()
});
// Ping first to register visitor, then send message
fetch(`/api/chat.php?action=ping&user_time=${encodeURIComponent(new Date().toLocaleString())}`)
.then(() => sendModalMessage(initialMessage))
.catch(err => console.error('Ping failed:', err));
// Start polling for modal
initModalChat();
}
let modalChatPolling = false;
function initModalChat() {
if (modalChatPolling) return; // Prevent multiple polling loops
modalChatPolling = true;
const modalChatForm = document.getElementById('modal-chat-form');
const modalChatInput = document.getElementById('modal-chat-input');
const modalChatUpload = document.getElementById('modal-chat-upload');
@ -510,6 +550,9 @@ function initModalChat() {
const modalPoll = async () => {
if (!document.getElementById('rechargeModal').classList.contains('show')) return;
try {
// Periodic ping to keep session alive and visitor status active
fetch(`/api/chat.php?action=ping&user_time=${encodeURIComponent(new Date().toLocaleString())}`);
const resp = await fetch('/api/chat.php?action=get_messages');
const data = await resp.json();
if (Array.isArray(data)) {
@ -558,7 +601,17 @@ function appendModalMessage(m) {
}
const isImage = text.indexOf('<img') !== -1;
const time = new Date(m.created_at.replace(/-/g, "/")).toLocaleTimeString('zh-CN', {hour:'2-digit', minute:'2-digit'});
let timeStr = '';
try {
if (m.created_at) {
const dateObj = m.created_at.includes('-') ? new Date(m.created_at.replace(/-/g, "/")) : new Date(m.created_at);
timeStr = dateObj.toLocaleTimeString('zh-CN', {hour:'2-digit', minute:'2-digit'});
} else {
timeStr = new Date().toLocaleTimeString('zh-CN', {hour:'2-digit', minute:'2-digit'});
}
} catch(e) {
timeStr = '--:--';
}
const html = `
<div class="mb-3 d-flex flex-column ${sender === 'user' ? 'align-items-end' : 'align-items-start'} modal-msg" data-modal-id="${m.id}">
@ -566,7 +619,7 @@ function appendModalMessage(m) {
<div class="message-content" style="text-shadow: 0 1px 2px rgba(0,0,0,0.2); font-size: 14px; line-height: 1.5;">
${text}
</div>
<div style="font-size: 9px; opacity: 0.6; position: absolute; bottom: 4px; ${sender === 'user' ? 'right: 12px;' : 'left: 12px;'} ${isImage ? 'background: rgba(0,0,0,0.5); padding: 2px 6px; border-radius: 4px; bottom: 8px;' : ''}">${time}</div>
<div style="font-size: 9px; opacity: 0.6; position: absolute; bottom: 4px; ${sender === 'user' ? 'right: 12px;' : 'left: 12px;'} ${isImage ? 'background: rgba(0,0,0,0.5); padding: 2px 6px; border-radius: 4px; bottom: 8px;' : ''}">${timeStr}</div>
</div>
</div>
`;
@ -582,70 +635,62 @@ function updateMatchingSide(info) {
side.innerHTML = `
<div class="position-absolute top-0 start-0 w-100 h-100 vibrancy-bg"></div>
<div class="position-absolute top-0 start-0 w-100 h-100 bg-black bg-opacity-30" style="z-index: 1;"></div>
<div class="position-absolute top-0 start-0 w-100 h-100 bg-black bg-opacity-40" style="z-index: 1; backdrop-filter: blur(2px);"></div>
<div class="text-center text-lg-start fade-in position-relative" style="z-index: 2;">
<div class="mb-5">
<div class="d-inline-flex align-items-center gap-2 px-3 py-1 rounded-pill bg-white bg-opacity-20 text-white small fw-bold mb-3 border border-white border-opacity-30 shadow-sm">
<i class="bi bi-check-circle-fill"></i> <?= __('account_matched') ?>
<div class="d-inline-flex align-items-center gap-2 px-3 py-1 rounded-pill bg-white bg-opacity-20 text-white small fw-bold mb-3 border border-white border-opacity-30 shadow-sm" style="backdrop-filter: blur(10px);">
<i class="bi bi-check-circle-fill text-success"></i> <?= __('account_matched') ?>
</div>
<h2 class="display-6 fw-bold text-white mb-3 text-shadow-heavy"><?= __('account_matched') ?></h2>
<p class="text-white fs-5 fw-bold opacity-100 text-shadow-medium"><?= __('account_matched_desc') ?></p>
<h2 class="display-6 fw-bold text-white mb-3 text-shadow-ultra"><?= __('account_matched') ?></h2>
<p class="text-white fs-5 fw-bold opacity-90 text-shadow-heavy"><?= __('account_matched_desc') ?></p>
</div>
<div class="mb-5 p-4 rounded-4 shadow-lg border border-white border-opacity-30" style="background: rgba(0,0,0,0.5); backdrop-filter: blur(25px);">
<div class="mb-5 p-4 rounded-4 shadow-2xl border border-white border-opacity-30" style="background: rgba(255,255,255,0.1); backdrop-filter: blur(40px);">
<div class="d-flex flex-column gap-4">
<div class="payment-item">
<div class="text-white small opacity-80 mb-1 fw-bold"><?= __('bank_name') ?></div>
<div class="d-flex justify-content-between align-items-center">
<div class="h5 mb-0 fw-bold text-white text-shadow-medium">${info.bank}</div>
<button class="btn btn-sm btn-light rounded-pill px-3 fw-bold shadow-sm" onclick="copyText('${info.bank}')"><?= __('copy_info') ?></button>
<div class="text-white small mb-1 fw-bold text-shadow-medium"><?= __('bank_name') ?></div>
<div class="d-flex justify-content-between align-items-center gap-3">
<div class="h5 mb-0 fw-bold text-white text-shadow-heavy" style="word-break: break-all;">${info.bank}</div>
<button class="btn btn-sm btn-light rounded-pill px-3 fw-bold shadow-sm flex-shrink-0" onclick="copyText('${info.bank}')"><?= __('copy_info') ?></button>
</div>
</div>
<div class="payment-item border-top border-white border-opacity-10 pt-3">
<div class="text-white small opacity-80 mb-1 fw-bold"><?= __('payee_name') ?></div>
<div class="d-flex justify-content-between align-items-center">
<div class="h5 mb-0 fw-bold text-white text-shadow-medium">${info.name}</div>
<button class="btn btn-sm btn-light rounded-pill px-3 fw-bold shadow-sm" onclick="copyText('${info.name}')"><?= __('copy_info') ?></button>
<div class="payment-item border-top border-white border-opacity-20 pt-3">
<div class="text-white small mb-1 fw-bold text-shadow-medium"><?= __('payee_name') ?></div>
<div class="d-flex justify-content-between align-items-center gap-3">
<div class="h5 mb-0 fw-bold text-white text-shadow-heavy" style="word-break: break-all;">${info.name}</div>
<button class="btn btn-sm btn-light rounded-pill px-3 fw-bold shadow-sm flex-shrink-0" onclick="copyText('${info.name}')"><?= __('copy_info') ?></button>
</div>
</div>
<div class="payment-item border-top border-white border-opacity-10 pt-3">
<div class="text-white small opacity-80 mb-1 fw-bold"><?= __('account_number') ?></div>
<div class="d-flex justify-content-between align-items-center">
<div class="h4 mb-0 fw-bold text-warning tracking-wider text-shadow-glow">${info.account}</div>
<button class="btn btn-sm btn-warning rounded-pill px-3 shadow-lg fw-bold" onclick="copyText('${info.account}')"><?= __('copy_info') ?></button>
<div class="payment-item border-top border-white border-opacity-20 pt-3">
<div class="text-white small mb-1 fw-bold text-shadow-medium"><?= __('account_number') ?></div>
<div class="d-flex justify-content-between align-items-center gap-3">
<div class="h4 mb-0 fw-bold text-warning tracking-wider text-shadow-glow" style="word-break: break-all; font-family: 'Courier New', monospace;">${info.account}</div>
<button class="btn btn-sm btn-warning rounded-pill px-3 shadow-lg fw-bold flex-shrink-0" onclick="copyText('${info.account}')"><?= __('copy_info') ?></button>
</div>
</div>
${info.note ? `
<div class="payment-item border-top border-white border-opacity-10 pt-3">
<div class="text-info small mb-1 fw-bold"><i class="bi bi-exclamation-circle me-1"></i><?= __('transfer_note') ?></div>
<div class="d-flex justify-content-between align-items-center">
<div class="fw-bold text-info text-shadow-glow-sm">${info.note}</div>
<button class="btn btn-sm btn-info text-white rounded-pill px-3 fw-bold shadow-sm" onclick="copyText('${info.note}')"><?= __('copy_info') ?></button>
<div class="payment-item border-top border-white border-opacity-20 pt-3">
<div class="text-warning small mb-1 fw-bold"><i class="bi bi-exclamation-circle me-1"></i><?= __('transfer_note') ?></div>
<div class="d-flex justify-content-between align-items-center gap-3">
<div class="fw-bold text-warning text-shadow-glow-sm" style="word-break: break-all;">${info.note}</div>
<button class="btn btn-sm btn-warning text-dark rounded-pill px-3 fw-bold shadow-sm flex-shrink-0" onclick="copyText('${info.note}')"><?= __('copy_info') ?></button>
</div>
</div>` : ''}
</div>
</div>
<div class="space-y-4">
<h6 class="text-white fw-bold mb-4 d-flex align-items-center gap-2 text-shadow-medium">
<i class="bi bi-info-circle text-white fs-5"></i> <?= __('transfer_steps_title') ?>
<h6 class="text-white fw-bold mb-4 d-flex align-items-center gap-2 text-shadow-heavy">
<i class="bi bi-info-circle-fill text-white fs-5"></i> <?= __('transfer_steps_title') ?>
</h6>
<div class="d-flex flex-column gap-3">
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-10 shadow-sm">
<div class="fw-bold text-warning fs-5 text-shadow-glow-sm">01</div>
<div class="text-white small lh-base fw-bold text-shadow-medium"><?= __('step_1') ?></div>
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-20 shadow-sm hover-scale-sm" style="backdrop-filter: blur(10px);">
<div class="fw-bold text-warning fs-5 text-shadow-glow-sm" style="min-width: 25px;">01</div>
<div class="text-white small lh-base fw-bold text-shadow-medium">完成转账后,请将转账凭证提交给在线客服</div>
</div>
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-10 shadow-sm">
<div class="fw-bold text-warning fs-5 text-shadow-glow-sm">02</div>
<div class="text-white small lh-base fw-bold text-shadow-medium"><?= __('step_2') ?></div>
</div>
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-10 shadow-sm">
<div class="fw-bold text-warning fs-5 text-shadow-glow-sm">03</div>
<div class="text-white small lh-base fw-bold text-shadow-medium"><?= __('step_3') ?></div>
</div>
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-10 shadow-sm">
<div class="fw-bold text-warning fs-5 text-shadow-glow-sm">04</div>
<div class="text-white small lh-base fw-bold text-shadow-medium"><?= __('step_4') ?></div>
<div class="d-flex gap-3 align-items-start p-3 rounded-3 bg-white bg-opacity-10 border border-white border-opacity-20 shadow-sm hover-scale-sm" style="backdrop-filter: blur(10px);">
<div class="fw-bold text-warning fs-5 text-shadow-glow-sm" style="min-width: 25px;">02</div>
<div class="text-white small lh-base fw-bold text-shadow-medium">客服将在核实资金后为您确认到账</div>
</div>
</div>
</div>
@ -692,6 +737,12 @@ function confirmFiatOrder() {
const estUsdt = amount / rate;
// Show loading state
const btn = event.target;
const originalText = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${originalText}`;
const formData = new FormData();
formData.append('action', 'recharge');
formData.append('amount', estUsdt);
@ -706,6 +757,8 @@ function confirmFiatOrder() {
})
.then(r => r.json())
.then(data => {
btn.disabled = false;
btn.innerHTML = originalText;
if (data.success) {
let message = `<?= __('recharge_msg_fiat') ?>`;
const preciseRes = (amount / rate).toFixed(4);
@ -718,18 +771,27 @@ function confirmFiatOrder() {
} else {
notify('error', data.error || '<?= __('request_failed') ?>');
}
})
.catch(() => {
btn.disabled = false;
btn.innerHTML = originalText;
});
}
function confirmCryptoOrder() {
const amountInput = document.getElementById('cryptoAmount');
const amount = parseFloat(amountInput.value);
const btn = event.target;
if (isNaN(amount) || amount <= 0) {
notify('warning', '<?= __("enter_amount") ?>');
return;
}
const originalText = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${originalText}`;
const formData = new FormData();
formData.append('action', 'recharge');
formData.append('amount', amount);
@ -741,17 +803,27 @@ function confirmCryptoOrder() {
body: formData
})
.then(r => r.json())
.then(data => {
.then(async data => {
btn.disabled = false;
btn.innerHTML = originalText;
if (data.success) {
let message = `<?= __('recharge_msg_crypto') ?>`;
message = message.replace('%uid%', userId)
.replace('%amount%', amount)
.replace('%network%', currentNetwork);
openRechargeModal(message);
// Send message to CS quietly for USDT
await sendModalMessage(message);
notify('success', '<?= __("recharge_success_title") ?>', '<?= __("recharge_success_text") ?>');
amountInput.value = '';
} else {
notify('error', data.error || '<?= __('request_failed') ?>');
}
})
.catch(() => {
btn.disabled = false;
btn.innerHTML = originalText;
});
}