123456
This commit is contained in:
parent
540176c668
commit
bb14c2ece7
@ -313,6 +313,9 @@ let currentUserContext = '';
|
|||||||
let lastMsgCount = 0;
|
let lastMsgCount = 0;
|
||||||
let notifySound = new Audio('https://assets.mixkit.co/active_storage/sfx/2358/2358-preview.mp3');
|
let notifySound = new Audio('https://assets.mixkit.co/active_storage/sfx/2358/2358-preview.mp3');
|
||||||
|
|
||||||
|
// Get API path dynamically
|
||||||
|
const apiPath = (window.location.origin + window.location.pathname).split('/admin/')[0] + '/api/';
|
||||||
|
|
||||||
async function refreshUsers() {
|
async function refreshUsers() {
|
||||||
try {
|
try {
|
||||||
const list = document.getElementById('user-list');
|
const list = document.getElementById('user-list');
|
||||||
@ -321,10 +324,17 @@ let notifySound = new Audio('https://assets.mixkit.co/active_storage/sfx/2358/23
|
|||||||
const searchInput = document.getElementById('user-search');
|
const searchInput = document.getElementById('user-search');
|
||||||
const search = searchInput ? searchInput.value.toLowerCase() : '';
|
const search = searchInput ? searchInput.value.toLowerCase() : '';
|
||||||
|
|
||||||
const r = await fetch('../api/chat.php?action=admin_get_all');
|
const r = await fetch(apiPath + 'chat.php?action=admin_get_all&v=' + Date.now());
|
||||||
if (!r.ok) return;
|
if (!r.ok) {
|
||||||
|
list.innerHTML = `<div class="p-4 text-center text-danger small">API 错误: ${r.status} ${r.statusText}</div>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const users = await r.json();
|
const users = await r.json();
|
||||||
|
if (users.success === false) {
|
||||||
|
list.innerHTML = `<div class="p-4 text-center text-danger small">服务器错误: ${users.error}</div>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (users.error || !Array.isArray(users)) return;
|
if (users.error || !Array.isArray(users)) return;
|
||||||
|
|
||||||
// Sound notification for new messages based on total unread count
|
// Sound notification for new messages based on total unread count
|
||||||
@ -452,14 +462,14 @@ let notifySound = new Audio('https://assets.mixkit.co/active_storage/sfx/2358/23
|
|||||||
fd.append('user_id', userId);
|
fd.append('user_id', userId);
|
||||||
fd.append('ip_address', ip);
|
fd.append('ip_address', ip);
|
||||||
fd.append('session_id', sid);
|
fd.append('session_id', sid);
|
||||||
fetch('../api/chat.php?action=mark_read', { method: 'POST', body: fd }).then(() => refreshUsers());
|
fetch(apiPath + 'chat.php?action=mark_read&v=' + Date.now(), { method: 'POST', body: fd }).then(() => refreshUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
async function recallMessage(msgId) {
|
async function recallMessage(msgId) {
|
||||||
if (!confirm('确定撤回该消息吗?')) return;
|
if (!confirm('确定撤回该消息吗?')) return;
|
||||||
const fd = new URLSearchParams();
|
const fd = new URLSearchParams();
|
||||||
fd.append('message_id', msgId);
|
fd.append('message_id', msgId);
|
||||||
const r = await fetch('../api/chat.php?action=admin_recall_message', { method: 'POST', body: fd });
|
const r = await fetch(apiPath + 'chat.php?action=admin_recall_message&v=' + Date.now(), { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
fetchMessages();
|
fetchMessages();
|
||||||
@ -473,7 +483,7 @@ async function deleteChat(userId, ip, sid, event) {
|
|||||||
fd.append('user_id', userId);
|
fd.append('user_id', userId);
|
||||||
fd.append('ip_address', ip);
|
fd.append('ip_address', ip);
|
||||||
fd.append('session_id', sid);
|
fd.append('session_id', sid);
|
||||||
const r = await fetch('../api/chat.php?action=admin_delete_user', { method: 'POST', body: fd });
|
const r = await fetch(apiPath + 'chat.php?action=admin_delete_user&v=' + Date.now(), { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
if (selectedSid == sid && selectedIp == ip && selectedUser == userId) {
|
if (selectedSid == sid && selectedIp == ip && selectedUser == userId) {
|
||||||
@ -500,7 +510,7 @@ async function deleteUser() {
|
|||||||
fd.append('user_id', selectedUser);
|
fd.append('user_id', selectedUser);
|
||||||
fd.append('ip_address', selectedIp);
|
fd.append('ip_address', selectedIp);
|
||||||
fd.append('session_id', selectedSid);
|
fd.append('session_id', selectedSid);
|
||||||
const r = await fetch('../api/chat.php?action=admin_delete_user', { method: 'POST', body: fd });
|
const r = await fetch(apiPath + 'chat.php?action=admin_delete_user&v=' + Date.now(), { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
selectedUser = null;
|
selectedUser = null;
|
||||||
@ -522,7 +532,7 @@ async function deleteUser() {
|
|||||||
async function fetchMessages() {
|
async function fetchMessages() {
|
||||||
if (!selectedIp && !selectedUser && !selectedSid) return;
|
if (!selectedIp && !selectedUser && !selectedSid) return;
|
||||||
try {
|
try {
|
||||||
const r = await fetch(`../api/chat.php?action=get_messages&user_id=${selectedUser}&ip=${selectedIp}&session_id=${selectedSid}`);
|
const r = await fetch(apiPath + `chat.php?action=get_messages&user_id=${selectedUser}&ip=${selectedIp}&session_id=${selectedSid}&v=${Date.now()}`);
|
||||||
const msgs = await r.json();
|
const msgs = await r.json();
|
||||||
if (!msgs || !Array.isArray(msgs)) return;
|
if (!msgs || !Array.isArray(msgs)) return;
|
||||||
|
|
||||||
@ -634,7 +644,7 @@ async function notifyMatchSuccess() {
|
|||||||
fd.append('account', account);
|
fd.append('account', account);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r = await fetch('../api/admin_recharge.php?action=match_success', { method: 'POST', body: fd });
|
const r = await fetch(apiPath + 'admin_recharge.php?action=match_success&v=' + Date.now(), { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
alert('匹配成功!状态已更新。若要向用户显示收款账户,请继续点击“发送账户”按钮。');
|
alert('匹配成功!状态已更新。若要向用户显示收款账户,请继续点击“发送账户”按钮。');
|
||||||
@ -663,7 +673,7 @@ async function sendPaymentInfo() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('Sending account info...', { bank, name, account });
|
console.log('Sending account info...', { bank, name, account });
|
||||||
const r = await fetch('../api/admin_recharge.php?action=send_account', { method: 'POST', body: fd });
|
const r = await fetch(apiPath + 'admin_recharge.php?action=send_account&v=' + Date.now(), { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
|
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
@ -709,7 +719,7 @@ document.getElementById('image-input').addEventListener('change', async (e) => {
|
|||||||
formData.append('session_id', selectedSid || '');
|
formData.append('session_id', selectedSid || '');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r = await fetch('../api/chat.php?action=upload_image', {
|
const r = await fetch(apiPath + 'chat.php?action=upload_image&v=' + Date.now(), {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
});
|
});
|
||||||
@ -759,7 +769,7 @@ document.getElementById('chat-form').addEventListener('submit', async (e) => {
|
|||||||
fd.append('session_id', selectedSid);
|
fd.append('session_id', selectedSid);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r = await fetch('../api/chat.php?action=admin_send', { method: 'POST', body: fd });
|
const r = await fetch(apiPath + 'chat.php?action=admin_send&v=' + Date.now(), { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
|
|
||||||
const tempMsg = document.querySelector(`[data-id="${tempId}"]`);
|
const tempMsg = document.querySelector(`[data-id="${tempId}"]`);
|
||||||
@ -781,7 +791,7 @@ document.getElementById('save-remark-btn').addEventListener('click', async () =>
|
|||||||
fd.append('session_id', selectedSid);
|
fd.append('session_id', selectedSid);
|
||||||
fd.append('remark', remark);
|
fd.append('remark', remark);
|
||||||
|
|
||||||
const r = await fetch('../api/chat.php?action=save_remark', { method: 'POST', body: fd });
|
const r = await fetch(apiPath + 'chat.php?action=save_remark&v=' + Date.now(), { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
alert('备注已保存');
|
alert('备注已保存');
|
||||||
|
|||||||
@ -281,21 +281,24 @@ function renderAdminPage($content, $title = '后台管理') {
|
|||||||
const visitedPages = JSON.parse(localStorage.getItem('visited_admin_pages') || '[]');
|
const visitedPages = JSON.parse(localStorage.getItem('visited_admin_pages') || '[]');
|
||||||
const currentPage = window.location.pathname;
|
const currentPage = window.location.pathname;
|
||||||
|
|
||||||
|
// Detect base path for API calls
|
||||||
|
const apiPath = (window.location.origin + window.location.pathname).split('/admin/')[0] + '/api/';
|
||||||
|
|
||||||
// Clear badges based on current page
|
// Clear badges based on current page
|
||||||
if (currentPage.includes('finance.php')) {
|
if (currentPage.includes('finance.php')) {
|
||||||
fetch('../api/admin_notifications.php?action=clear&type=finance');
|
fetch(apiPath + 'admin_notifications.php?action=clear&type=finance&v=' + Date.now());
|
||||||
} else if (currentPage.includes('kyc.php')) {
|
} else if (currentPage.includes('kyc.php')) {
|
||||||
fetch('../api/admin_notifications.php?action=clear&type=kyc');
|
fetch(apiPath + 'admin_notifications.php?action=clear&type=kyc&v=' + Date.now());
|
||||||
} else if (currentPage.includes('binary.php')) {
|
} else if (currentPage.includes('binary.php')) {
|
||||||
fetch('../api/admin_notifications.php?action=clear&type=binary');
|
fetch(apiPath + 'admin_notifications.php?action=clear&type=binary&v=' + Date.now());
|
||||||
} else if (currentPage.includes('contract.php')) {
|
} else if (currentPage.includes('contract.php')) {
|
||||||
fetch('../api/admin_notifications.php?action=clear&type=contract');
|
fetch(apiPath + 'admin_notifications.php?action=clear&type=contract&v=' + Date.now());
|
||||||
} else if (currentPage.includes('spot.php')) {
|
} else if (currentPage.includes('spot.php')) {
|
||||||
fetch('../api/admin_notifications.php?action=clear&type=spot');
|
fetch(apiPath + 'admin_notifications.php?action=clear&type=spot&v=' + Date.now());
|
||||||
} else if (currentPage.includes('customer_service.php')) {
|
} else if (currentPage.includes('customer_service.php')) {
|
||||||
fetch('../api/admin_notifications.php?action=clear&type=messages');
|
fetch(apiPath + 'admin_notifications.php?action=clear&type=messages&v=' + Date.now());
|
||||||
} else if (currentPage.includes('users.php')) {
|
} else if (currentPage.includes('users.php')) {
|
||||||
fetch('../api/admin_notifications.php?action=clear&type=users');
|
fetch(apiPath + 'admin_notifications.php?action=clear&type=users&v=' + Date.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll('.card-dismissible').forEach(card => {
|
document.querySelectorAll('.card-dismissible').forEach(card => {
|
||||||
@ -351,7 +354,8 @@ function renderAdminPage($content, $title = '后台管理') {
|
|||||||
function checkNotifications() {
|
function checkNotifications() {
|
||||||
const currentPage = window.location.pathname;
|
const currentPage = window.location.pathname;
|
||||||
const isDashboard = currentPage.includes('index.php') || currentPage.endsWith('/admin/');
|
const isDashboard = currentPage.includes('index.php') || currentPage.endsWith('/admin/');
|
||||||
const url = isDashboard ? '../api/admin_notifications.php?stats=1' : '../api/admin_notifications.php';
|
const apiPath = (window.location.origin + window.location.pathname).split('/admin/')[0] + '/api/';
|
||||||
|
const url = apiPath + 'admin_notifications.php?v=' + Date.now() + (isDashboard ? '&stats=1' : '');
|
||||||
|
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
|
|||||||
97
api/chat.php
97
api/chat.php
@ -233,71 +233,55 @@ if ($action === 'admin_get_all') {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// Improved query to get all active chat sessions.
|
// Simplified and robust query for deployment compatibility
|
||||||
// We group by user_id if it's set (>0).
|
|
||||||
// If user_id is 0, we group by session_id.
|
|
||||||
// If session_id is also empty, we group by IP.
|
|
||||||
$stmt = db()->query("
|
$stmt = db()->query("
|
||||||
SELECT
|
SELECT
|
||||||
v.final_user_id as user_id,
|
v.final_user_id as user_id,
|
||||||
v.effective_ip as ip_address,
|
MAX(v.effective_ip) as ip_address,
|
||||||
v.effective_sid as session_id,
|
MAX(v.effective_sid) as session_id,
|
||||||
v.unread_count,
|
SUM(v.is_unread) as unread_count,
|
||||||
|
MAX(v.has_recharge) as has_recharge,
|
||||||
CASE
|
CASE
|
||||||
WHEN m.message LIKE '<img%' THEN '[图片消息]'
|
WHEN m.message LIKE '<img%' THEN '[图片消息]'
|
||||||
WHEN (m.message IS NULL OR m.message = '') AND v.has_recharge = 1 THEN '[充值申请]'
|
WHEN (m.message IS NULL OR m.message = '') AND MAX(v.has_recharge) = 1 THEN '[充值申请]'
|
||||||
ELSE COALESCE(m.message, '新会话')
|
ELSE COALESCE(m.message, '新会话')
|
||||||
END as message,
|
END as message,
|
||||||
COALESCE(m.created_at, v.last_activity) as created_at,
|
COALESCE(m.created_at, MAX(v.last_activity)) as created_at,
|
||||||
COALESCE(u.username, u.email, CONCAT('访客 ', COALESCE(NULLIF(v.effective_ip, ''), '0.0.0.0'))) as username,
|
COALESCE(u.username, u.email, CONCAT('访客 ', COALESCE(NULLIF(MAX(v.effective_ip), ''), '0.0.0.0'))) as username,
|
||||||
IFNULL(u.uid, '---') as uid,
|
IFNULL(u.uid, '---') as uid,
|
||||||
IFNULL(u.registration_ip, '---') as registration_ip,
|
IFNULL(u.registration_ip, '---') as registration_ip,
|
||||||
IFNULL(r.remark, '') as remark,
|
IFNULL(r.remark, '') as remark,
|
||||||
IFNULL(v.user_time, '---') as user_time
|
IFNULL(MAX(v.user_time), '---') as user_time
|
||||||
FROM (
|
FROM (
|
||||||
SELECT
|
SELECT
|
||||||
final_user_id,
|
IFNULL(user_id, 0) as final_user_id,
|
||||||
SUBSTRING_INDEX(GROUP_CONCAT(effective_ip ORDER BY last_activity DESC SEPARATOR '|'), '|', 1) as effective_ip,
|
CASE WHEN ip_address = '---' THEN '' ELSE IFNULL(ip_address, '') END as effective_ip,
|
||||||
SUBSTRING_INDEX(GROUP_CONCAT(effective_sid ORDER BY last_activity DESC SEPARATOR '|'), '|', 1) as effective_sid,
|
IFNULL(session_id, '') as effective_sid,
|
||||||
MAX(last_activity) as last_activity,
|
created_at as last_activity,
|
||||||
MAX(user_time) as user_time,
|
NULL as user_time,
|
||||||
MAX(has_recharge) as has_recharge,
|
0 as has_recharge,
|
||||||
SUM(is_unread) as unread_count
|
CASE WHEN sender = 'user' AND is_read = 0 THEN 1 ELSE 0 END as is_unread
|
||||||
FROM (
|
FROM messages
|
||||||
SELECT
|
UNION ALL
|
||||||
IFNULL(user_id, 0) as final_user_id,
|
SELECT
|
||||||
CASE WHEN ip_address = '---' THEN '' ELSE IFNULL(ip_address, '') END as effective_ip,
|
IFNULL(user_id, 0) as final_user_id,
|
||||||
IFNULL(session_id, '') as effective_sid,
|
CASE WHEN ip_address = '---' THEN '' ELSE IFNULL(ip_address, '') END as effective_ip,
|
||||||
created_at as last_activity,
|
IFNULL(session_id, '') as effective_sid,
|
||||||
NULL as user_time,
|
last_ping as last_activity,
|
||||||
0 as has_recharge,
|
user_time,
|
||||||
CASE WHEN sender = 'user' AND is_read = 0 THEN 1 ELSE 0 END as is_unread
|
0 as has_recharge,
|
||||||
FROM messages m
|
0 as is_unread
|
||||||
UNION ALL
|
FROM chat_visitors
|
||||||
SELECT
|
UNION ALL
|
||||||
IFNULL(user_id, 0) as final_user_id,
|
SELECT
|
||||||
CASE WHEN ip_address = '---' THEN '' ELSE IFNULL(ip_address, '') END as effective_ip,
|
IFNULL(user_id, 0) as final_user_id,
|
||||||
IFNULL(session_id, '') as effective_sid,
|
CASE WHEN ip_address = '---' THEN '' ELSE IFNULL(ip_address, '') END as effective_ip,
|
||||||
last_ping as last_activity,
|
'' as effective_sid,
|
||||||
user_time,
|
created_at as last_activity,
|
||||||
0 as has_recharge,
|
NULL as user_time,
|
||||||
0 as is_unread
|
1 as has_recharge,
|
||||||
FROM chat_visitors cv
|
0 as is_unread
|
||||||
UNION ALL
|
FROM finance_requests WHERE type='recharge' AND status NOT IN ('3', '4')
|
||||||
SELECT
|
|
||||||
IFNULL(user_id, 0) as final_user_id,
|
|
||||||
CASE WHEN ip_address = '---' THEN '' ELSE IFNULL(ip_address, '') END as effective_ip,
|
|
||||||
'' as effective_sid,
|
|
||||||
created_at as last_activity,
|
|
||||||
NULL as user_time,
|
|
||||||
1 as has_recharge,
|
|
||||||
0 as is_unread
|
|
||||||
FROM finance_requests fr WHERE fr.status NOT IN ('3', '4')
|
|
||||||
) t1
|
|
||||||
GROUP BY
|
|
||||||
CASE WHEN final_user_id > 0 THEN final_user_id ELSE 0 END,
|
|
||||||
CASE WHEN final_user_id = 0 THEN effective_sid ELSE '' END,
|
|
||||||
CASE WHEN final_user_id = 0 AND effective_sid = '' THEN effective_ip ELSE '' END
|
|
||||||
) v
|
) v
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT m1.*,
|
SELECT m1.*,
|
||||||
@ -322,6 +306,10 @@ if ($action === 'admin_get_all') {
|
|||||||
(v.final_user_id = 0 AND v.effective_sid != '' AND v.effective_sid = r.session_id) OR
|
(v.final_user_id = 0 AND v.effective_sid != '' AND v.effective_sid = r.session_id) OR
|
||||||
(v.final_user_id = 0 AND v.effective_sid = '' AND v.effective_ip = r.ip_address)
|
(v.final_user_id = 0 AND v.effective_sid = '' AND v.effective_ip = r.ip_address)
|
||||||
)
|
)
|
||||||
|
GROUP BY
|
||||||
|
v.final_user_id,
|
||||||
|
CASE WHEN v.final_user_id = 0 THEN v.effective_sid ELSE '' END,
|
||||||
|
CASE WHEN v.final_user_id = 0 AND v.effective_sid = '' THEN v.effective_ip ELSE '' END
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
");
|
");
|
||||||
$results = $stmt->fetchAll();
|
$results = $stmt->fetchAll();
|
||||||
@ -332,7 +320,8 @@ if ($action === 'admin_get_all') {
|
|||||||
echo json_encode($results);
|
echo json_encode($results);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("Chat API Error: " . $e->getMessage());
|
error_log("Chat API Error: " . $e->getMessage());
|
||||||
echo json_encode(['error' => $e->getMessage()]);
|
// Return structured error for front-end handling
|
||||||
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
assets/pasted-20260222-081324-8196b7b9.png
Normal file
BIN
assets/pasted-20260222-081324-8196b7b9.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
@ -28,8 +28,13 @@ function getRealIP() {
|
|||||||
return $_SERVER['HTTP_X_REAL_IP'];
|
return $_SERVER['HTTP_X_REAL_IP'];
|
||||||
}
|
}
|
||||||
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||||
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
$ips = array_map('trim', explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
|
||||||
return trim($ips[0]);
|
foreach ($ips as $ip) {
|
||||||
|
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||||
|
return $ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ips[0];
|
||||||
}
|
}
|
||||||
return $_SERVER['REMOTE_ADDR'];
|
return $_SERVER['REMOTE_ADDR'];
|
||||||
}
|
}
|
||||||
|
|||||||
22
recharge.php
22
recharge.php
@ -405,6 +405,7 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
|
|||||||
let currentNetwork = 'TRC20';
|
let currentNetwork = 'TRC20';
|
||||||
let currentAddress = '<?= $trc20_addr ?>';
|
let currentAddress = '<?= $trc20_addr ?>';
|
||||||
const userId = '<?= $user['uid'] ?? $user['id'] ?>';
|
const userId = '<?= $user['uid'] ?? $user['id'] ?>';
|
||||||
|
const apiPath = (window.location.origin + window.location.pathname).split('/recharge.php')[0] + '/api/';
|
||||||
let rechargeCountdownInterval;
|
let rechargeCountdownInterval;
|
||||||
let modalChatLastIds = new Set();
|
let modalChatLastIds = new Set();
|
||||||
let remainingSeconds = 1800;
|
let remainingSeconds = 1800;
|
||||||
@ -430,7 +431,7 @@ async function updateRate() {
|
|||||||
|
|
||||||
// Try to get fresh rates
|
// Try to get fresh rates
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('api/exchange.php');
|
const resp = await fetch(apiPath + 'exchange.php?v=' + Date.now());
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
if (data.success && data.rates) {
|
if (data.success && data.rates) {
|
||||||
exchangeRates = data.rates;
|
exchangeRates = data.rates;
|
||||||
@ -496,7 +497,7 @@ function finishTransfer() {
|
|||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('action', 'complete_transfer');
|
formData.append('action', 'complete_transfer');
|
||||||
formData.append('order_id', orderId);
|
formData.append('order_id', orderId);
|
||||||
fetch('api/finance.php', { method: 'POST', body: formData })
|
fetch(apiPath + 'finance.php?v=' + Date.now(), { method: 'POST', body: formData })
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => { if (data.success) renderRechargeUI({status: 'finished'}); });
|
.then(data => { if (data.success) renderRechargeUI({status: 'finished'}); });
|
||||||
} else {
|
} else {
|
||||||
@ -552,8 +553,7 @@ function startStatusPolling(order_id) {
|
|||||||
const modalEl = document.getElementById('rechargeModal');
|
const modalEl = document.getElementById('rechargeModal');
|
||||||
if (!modalEl || !modalEl.classList.contains('show')) return;
|
if (!modalEl || !modalEl.classList.contains('show')) return;
|
||||||
try {
|
try {
|
||||||
const path = (window.REL_PATH || '') + `api/recharge_status.php?id=${order_id}&_t=${Date.now()}`;
|
const r = await fetch(apiPath + `recharge_status.php?id=${order_id}&v=${Date.now()}`);
|
||||||
const r = await fetch(path);
|
|
||||||
const data = await r.json();
|
const data = await r.json();
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
console.log('Order status update:', data.status, data);
|
console.log('Order status update:', data.status, data);
|
||||||
@ -745,7 +745,7 @@ function initModalChat() {
|
|||||||
scrollModalToBottom();
|
scrollModalToBottom();
|
||||||
const formData = new FormData(); formData.append('file', file); formData.append('action', 'upload_image');
|
const formData = new FormData(); formData.append('file', file); formData.append('action', 'upload_image');
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('api/chat.php', { method: 'POST', body: formData }), data = await resp.json();
|
const resp = await fetch(apiPath + 'chat.php?v=' + Date.now(), { method: 'POST', body: formData }), data = await resp.json();
|
||||||
document.querySelector(`[data-modal-id="${tempId}"]`)?.remove();
|
document.querySelector(`[data-modal-id="${tempId}"]`)?.remove();
|
||||||
if (data.success) { appendModalMessage(data.message); scrollModalToBottom(); }
|
if (data.success) { appendModalMessage(data.message); scrollModalToBottom(); }
|
||||||
} catch (err) { console.error(err); }
|
} catch (err) { console.error(err); }
|
||||||
@ -757,7 +757,7 @@ function initModalChat() {
|
|||||||
appendModalMessage({ id: tempId, sender: 'user', message: msg, created_at: new Date().toISOString() });
|
appendModalMessage({ id: tempId, sender: 'user', message: msg, created_at: new Date().toISOString() });
|
||||||
scrollModalToBottom();
|
scrollModalToBottom();
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('api/chat.php?action=send_message', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${encodeURIComponent(msg)}` });
|
const resp = await fetch(apiPath + 'chat.php?action=send_message&v=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${encodeURIComponent(msg)}` });
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
document.querySelector(`[data-modal-id="${tempId}"]`)?.remove();
|
document.querySelector(`[data-modal-id="${tempId}"]`)?.remove();
|
||||||
if (data.success) { appendModalMessage(data.message); scrollModalToBottom(); }
|
if (data.success) { appendModalMessage(data.message); scrollModalToBottom(); }
|
||||||
@ -769,8 +769,8 @@ function initModalChat() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
fetch(`api/chat.php?action=ping&user_time=${encodeURIComponent(new Date().toLocaleString())}`);
|
fetch(apiPath + `chat.php?action=ping&user_time=${encodeURIComponent(new Date().toLocaleString())}&v=` + Date.now());
|
||||||
const resp = await fetch('api/chat.php?action=get_messages'), data = await resp.json();
|
const resp = await fetch(apiPath + 'chat.php?action=get_messages&v=' + Date.now()), data = await resp.json();
|
||||||
if (Array.isArray(data)) { data.forEach(m => { if (!modalChatLastIds.has(m.id)) { appendModalMessage(m); modalChatLastIds.add(m.id); scrollModalToBottom(); } }); }
|
if (Array.isArray(data)) { data.forEach(m => { if (!modalChatLastIds.has(m.id)) { appendModalMessage(m); modalChatLastIds.add(m.id); scrollModalToBottom(); } }); }
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
setTimeout(modalPoll, 2000);
|
setTimeout(modalPoll, 2000);
|
||||||
@ -779,7 +779,7 @@ function initModalChat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function sendModalMessage(msg) {
|
async function sendModalMessage(msg) {
|
||||||
try { await fetch('api/chat.php?action=send_message', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${encodeURIComponent(msg)}` }); } catch (err) {}
|
try { await fetch(apiPath + 'chat.php?action=send_message&v=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${encodeURIComponent(msg)}` }); } catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendModalMessage(m) {
|
function appendModalMessage(m) {
|
||||||
@ -812,7 +812,7 @@ function confirmFiatOrder(btn, event) {
|
|||||||
if (isNaN(amount) || amount <= 0) { notify('warning', '<?= __("enter_amount") ?>'); return; }
|
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 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 / rate); formData.append('symbol', 'USDT'); formData.append('fiat_amount', amount); formData.append('fiat_currency', currency); formData.append('method', '<?= __("fiat_recharge") ?> (' + currency + ')');
|
const formData = new FormData(); formData.append('action', 'recharge'); formData.append('amount', amount / rate); formData.append('symbol', 'USDT'); formData.append('fiat_amount', amount); formData.append('fiat_currency', currency); formData.append('method', '<?= __("fiat_recharge") ?> (' + currency + ')');
|
||||||
fetch((window.REL_PATH || '') + 'api/finance.php', { method: 'POST', body: formData }).then(r => r.json()).then(data => {
|
fetch(apiPath + 'finance.php?v=' + Date.now(), { method: 'POST', body: formData }).then(r => r.json()).then(data => {
|
||||||
btn.disabled = false; btn.innerHTML = originalText;
|
btn.disabled = false; btn.innerHTML = originalText;
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
let msg = `<?= __("recharge_msg_fiat") ?>`;
|
let msg = `<?= __("recharge_msg_fiat") ?>`;
|
||||||
@ -832,7 +832,7 @@ function confirmCryptoOrder(btn, event) {
|
|||||||
if (isNaN(amount) || amount <= 0) { notify('warning', '<?= __("enter_amount") ?>'); return; }
|
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 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); formData.append('symbol', 'USDT'); formData.append('method', currentNetwork);
|
const formData = new FormData(); formData.append('action', 'recharge'); formData.append('amount', amount); formData.append('symbol', 'USDT'); formData.append('method', currentNetwork);
|
||||||
fetch((window.REL_PATH || '') + 'api/finance.php', { method: 'POST', body: formData }).then(r => r.json()).then(data => {
|
fetch(apiPath + 'finance.php?v=' + Date.now(), { method: 'POST', body: formData }).then(r => r.json()).then(data => {
|
||||||
btn.disabled = false; btn.innerHTML = originalText;
|
btn.disabled = false; btn.innerHTML = originalText;
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
let msg = `<?= __("recharge_msg_crypto") ?>`;
|
let msg = `<?= __("recharge_msg_crypto") ?>`;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user