更新部署
This commit is contained in:
parent
194fc7a771
commit
1adae4ff1b
@ -251,10 +251,6 @@ ob_start();
|
|||||||
<div class="alert alert-info small border-0 bg-light text-primary">
|
<div class="alert alert-info small border-0 bg-light text-primary">
|
||||||
<i class="bi bi-info-circle-fill me-2"></i>填写后点击发送,前端充值弹窗将自动切换并显示此账户。
|
<i class="bi bi-info-circle-fill me-2"></i>填写后点击发送,前端充值弹窗将自动切换并显示此账户。
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label small fw-bold text-muted">充值金额 (Amount)</label>
|
|
||||||
<input type="number" id="pay-amount" class="form-control form-control-lg fs-6 fw-bold text-danger" placeholder="0.00" step="0.01">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label small fw-bold text-muted">银行名称 / 支付方式 (Bank Name)</label>
|
<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.">
|
<input type="text" id="pay-bank" class="form-control form-control-lg fs-6" placeholder="例如: 建设银行, Alipay, TRC20, etc.">
|
||||||
@ -392,12 +388,17 @@ let notifySound = new Audio('https://assets.mixkit.co/active_storage/sfx/2358/23
|
|||||||
const jsName = username.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
const jsName = username.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
||||||
const jsRemark = rawRemark.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
const jsRemark = rawRemark.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
||||||
|
|
||||||
|
const unreadCount = parseInt(u.unread_count || 0);
|
||||||
|
|
||||||
html += `
|
html += `
|
||||||
<div class="user-card ${isActive ? 'active' : ''}"
|
<div class="user-card ${isActive ? 'active' : ''}"
|
||||||
onclick="openChat('${userId}', '${rawIp}', '${rawSid}', '${jsName}', '${uid}', '${jsRemark}', '${userTime}', '${registrationIp}')">
|
onclick="openChat('${userId}', '${rawIp}', '${rawSid}', '${jsName}', '${uid}', '${jsRemark}', '${userTime}', '${registrationIp}')">
|
||||||
<i class="bi bi-trash text-muted delete-chat-btn" title="删除会话" onclick="deleteChat('${userId}', '${rawIp}', '${rawSid}', event)"></i>
|
<i class="bi bi-trash text-muted delete-chat-btn" title="删除会话" onclick="deleteChat('${userId}', '${rawIp}', '${rawSid}', event)"></i>
|
||||||
<div class="d-flex justify-content-between mb-1">
|
<div class="d-flex justify-content-between mb-1">
|
||||||
<span class="fw-bold small text-truncate" style="max-width: 150px;">${username}</span>
|
<span class="fw-bold small text-truncate" style="max-width: 150px;">
|
||||||
|
${username}
|
||||||
|
${unreadCount > 0 ? `<span class="badge bg-danger rounded-pill ms-1" style="font-size: 9px; padding: 2px 5px;">${unreadCount}</span>` : ''}
|
||||||
|
</span>
|
||||||
<span class="text-muted" style="font-size: 10px;">${isNaN(lastTime.getTime()) ? '---' : lastTime.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit'})}</span>
|
<span class="text-muted" style="font-size: 10px;">${isNaN(lastTime.getTime()) ? '---' : lastTime.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit'})}</span>
|
||||||
</div>
|
</div>
|
||||||
${rawRemark ? `<div class="small text-danger text-truncate mb-1" style="font-size: 11px;">[备注: ${rawRemark}]</div>` : ''}
|
${rawRemark ? `<div class="small text-danger text-truncate mb-1" style="font-size: 11px;">[备注: ${rawRemark}]</div>` : ''}
|
||||||
@ -448,7 +449,13 @@ let notifySound = new Audio('https://assets.mixkit.co/active_storage/sfx/2358/23
|
|||||||
|
|
||||||
lastMsgId = 0;
|
lastMsgId = 0;
|
||||||
fetchMessages();
|
fetchMessages();
|
||||||
refreshUsers();
|
|
||||||
|
// Mark as read immediately when opening chat
|
||||||
|
const fd = new URLSearchParams();
|
||||||
|
fd.append('user_id', userId);
|
||||||
|
fd.append('ip_address', ip);
|
||||||
|
fd.append('session_id', sid);
|
||||||
|
fetch('/api/chat.php?action=mark_read', { method: 'POST', body: fd }).then(() => refreshUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
async function recallMessage(msgId) {
|
async function recallMessage(msgId) {
|
||||||
@ -617,7 +624,6 @@ async function notifyMatchSuccess() {
|
|||||||
const bank = document.getElementById('pay-bank').value.trim();
|
const bank = document.getElementById('pay-bank').value.trim();
|
||||||
const name = document.getElementById('pay-name').value.trim();
|
const name = document.getElementById('pay-name').value.trim();
|
||||||
const account = document.getElementById('pay-account').value.trim();
|
const account = document.getElementById('pay-account').value.trim();
|
||||||
const amount = document.getElementById('pay-amount').value.trim();
|
|
||||||
|
|
||||||
if (!bank || !name || !account) {
|
if (!bank || !name || !account) {
|
||||||
alert('请完整填写收款信息(银行、姓名、账号)');
|
alert('请完整填写收款信息(银行、姓名、账号)');
|
||||||
@ -629,7 +635,6 @@ async function notifyMatchSuccess() {
|
|||||||
fd.append('bank', bank);
|
fd.append('bank', bank);
|
||||||
fd.append('name', name);
|
fd.append('name', name);
|
||||||
fd.append('account', account);
|
fd.append('account', account);
|
||||||
if (amount) fd.append('amount', amount);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r = await fetch('/api/admin_recharge.php?action=match_success', { method: 'POST', body: fd });
|
const r = await fetch('/api/admin_recharge.php?action=match_success', { method: 'POST', body: fd });
|
||||||
@ -647,7 +652,6 @@ async function sendPaymentInfo() {
|
|||||||
const bank = document.getElementById('pay-bank').value.trim();
|
const bank = document.getElementById('pay-bank').value.trim();
|
||||||
const name = document.getElementById('pay-name').value.trim();
|
const name = document.getElementById('pay-name').value.trim();
|
||||||
const account = document.getElementById('pay-account').value.trim();
|
const account = document.getElementById('pay-account').value.trim();
|
||||||
const amount = document.getElementById('pay-amount').value.trim();
|
|
||||||
|
|
||||||
if (!bank || !name || !account) {
|
if (!bank || !name || !account) {
|
||||||
alert('请完整填写收款信息');
|
alert('请完整填写收款信息');
|
||||||
@ -659,10 +663,9 @@ async function sendPaymentInfo() {
|
|||||||
fd.append('bank', bank);
|
fd.append('bank', bank);
|
||||||
fd.append('name', name);
|
fd.append('name', name);
|
||||||
fd.append('account', account);
|
fd.append('account', account);
|
||||||
if (amount) fd.append('amount', amount);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('Sending account info...', { bank, name, account, amount });
|
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('/api/admin_recharge.php?action=send_account', { method: 'POST', body: fd });
|
||||||
const res = await r.json();
|
const res = await r.json();
|
||||||
|
|
||||||
|
|||||||
@ -123,6 +123,14 @@ function renderAdminPage($content, $title = '后台管理') {
|
|||||||
.nav-link i {
|
.nav-link i {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
.badge-dot {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #dc3545;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
.card {
|
.card {
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -192,19 +200,19 @@ function renderAdminPage($content, $title = '后台管理') {
|
|||||||
<!-- 7. 秒合约管理 -->
|
<!-- 7. 秒合约管理 -->
|
||||||
<a href="/admin/binary.php" class="nav-link <?= $current_page == 'binary.php' ? 'active' : '' ?>">
|
<a href="/admin/binary.php" class="nav-link <?= $current_page == 'binary.php' ? 'active' : '' ?>">
|
||||||
<i class="bi bi-clock"></i> <?= __('sec_contract_management') ?>
|
<i class="bi bi-clock"></i> <?= __('sec_contract_management') ?>
|
||||||
<span class="badge bg-info rounded-pill ms-auto d-none" id="binary-badge">0</span>
|
<span class="badge bg-danger rounded-pill ms-auto d-none" id="binary-badge">0</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- 8. 现货管理 -->
|
<!-- 8. 现货管理 -->
|
||||||
<a href="/admin/spot.php" class="nav-link <?= $current_page == 'spot.php' ? 'active' : '' ?>">
|
<a href="/admin/spot.php" class="nav-link <?= $current_page == 'spot.php' ? 'active' : '' ?>">
|
||||||
<i class="bi bi-currency-exchange"></i> <?= __('spot_trading') ?>
|
<i class="bi bi-currency-exchange"></i> <?= __('spot_trading') ?>
|
||||||
<span class="badge bg-info rounded-pill ms-auto d-none" id="spot-badge">0</span>
|
<span class="badge bg-danger rounded-pill ms-auto d-none" id="spot-badge">0</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- 9. 合约管理 -->
|
<!-- 9. 合约管理 -->
|
||||||
<a href="/admin/contract.php" class="nav-link <?= $current_page == 'contract.php' ? 'active' : '' ?>">
|
<a href="/admin/contract.php" class="nav-link <?= $current_page == 'contract.php' ? 'active' : '' ?>">
|
||||||
<i class="bi bi-layers"></i> <?= __('contract_trading') ?>
|
<i class="bi bi-layers"></i> <?= __('contract_trading') ?>
|
||||||
<span class="badge bg-info rounded-pill ms-auto d-none" id="contract-badge">0</span>
|
<span class="badge bg-danger rounded-pill ms-auto d-none" id="contract-badge">0</span>
|
||||||
</a>
|
</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
@ -227,7 +235,7 @@ function renderAdminPage($content, $title = '后台管理') {
|
|||||||
<!-- 13. 在线客服 -->
|
<!-- 13. 在线客服 -->
|
||||||
<a href="/admin/customer_service.php" class="nav-link <?= $current_page == 'customer_service.php' ? 'active' : '' ?>">
|
<a href="/admin/customer_service.php" class="nav-link <?= $current_page == 'customer_service.php' ? 'active' : '' ?>">
|
||||||
<i class="bi bi-headset"></i> <?= __('online_support') ?>
|
<i class="bi bi-headset"></i> <?= __('online_support') ?>
|
||||||
<span class="badge bg-warning rounded-pill ms-auto d-none" id="messages-badge">0</span>
|
<span class="badge bg-danger rounded-pill ms-auto d-none" id="messages-badge">0</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- 14. 后台设置 -->
|
<!-- 14. 后台设置 -->
|
||||||
@ -456,8 +464,8 @@ function renderAdminPage($content, $title = '后台管理') {
|
|||||||
.catch(e => console.error('Notification check failed:', e));
|
.catch(e => console.error('Notification check failed:', e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check every 10 seconds
|
// Check every 2 seconds
|
||||||
setInterval(checkNotifications, 10000);
|
setInterval(checkNotifications, 2000);
|
||||||
checkNotifications();
|
checkNotifications();
|
||||||
</script>
|
</script>
|
||||||
<!-- Lightbox for Chat Images -->
|
<!-- Lightbox for Chat Images -->
|
||||||
|
|||||||
@ -36,14 +36,6 @@ $active_contract = 0;
|
|||||||
$new_messages = 0;
|
$new_messages = 0;
|
||||||
$new_registrations = 0;
|
$new_registrations = 0;
|
||||||
|
|
||||||
$cleared_recharge = $_SESSION['admin_cleared_finance'] ?? 0;
|
|
||||||
$cleared_kyc = $_SESSION['admin_cleared_kyc'] ?? 0;
|
|
||||||
$cleared_binary = $_SESSION['admin_cleared_binary'] ?? 0;
|
|
||||||
$cleared_spot = $_SESSION['admin_cleared_spot'] ?? 0;
|
|
||||||
$cleared_contract = $_SESSION['admin_cleared_contract'] ?? 0;
|
|
||||||
$cleared_messages = $_SESSION['admin_cleared_messages'] ?? 0;
|
|
||||||
$cleared_users = $_SESSION['admin_cleared_users'] ?? 0;
|
|
||||||
|
|
||||||
function getCount($db, $sql, $params) {
|
function getCount($db, $sql, $params) {
|
||||||
$stmt = $db->prepare($sql);
|
$stmt = $db->prepare($sql);
|
||||||
$stmt->execute($params);
|
$stmt->execute($params);
|
||||||
@ -52,27 +44,27 @@ function getCount($db, $sql, $params) {
|
|||||||
|
|
||||||
if ($admin['is_agent']) {
|
if ($admin['is_agent']) {
|
||||||
$agent_id = $admin_id;
|
$agent_id = $admin_id;
|
||||||
$pending_recharge = getCount($db, "SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'recharge' AND r.status NOT IN ('3', '4') AND u.agent_id = ? AND UNIX_TIMESTAMP(r.created_at) > ?", [$agent_id, $cleared_recharge]);
|
$pending_recharge = getCount($db, "SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'recharge' AND r.status = '0' AND u.agent_id = ?", [$agent_id]);
|
||||||
$pending_withdrawal = getCount($db, "SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'withdrawal' AND r.status NOT IN ('3', '4') AND u.agent_id = ? AND UNIX_TIMESTAMP(r.created_at) > ?", [$agent_id, $cleared_recharge]);
|
$pending_withdrawal = getCount($db, "SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'withdrawal' AND r.status = '0' AND u.agent_id = ?", [$agent_id]);
|
||||||
$pending_kyc = getCount($db, "SELECT COUNT(*) FROM users WHERE kyc_status = 1 AND agent_id = ? AND UNIX_TIMESTAMP(created_at) > ?", [$agent_id, $cleared_kyc]);
|
$pending_kyc = getCount($db, "SELECT COUNT(*) FROM users WHERE kyc_status = 1 AND agent_id = ?", [$agent_id]);
|
||||||
$active_binary = getCount($db, "SELECT COUNT(*) FROM binary_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND u.agent_id = ? AND UNIX_TIMESTAMP(o.created_at) > ?", [$agent_id, $cleared_binary]);
|
$active_binary = getCount($db, "SELECT COUNT(*) FROM binary_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND u.agent_id = ?", [$agent_id]);
|
||||||
$active_spot = getCount($db, "SELECT COUNT(*) FROM spot_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 0 AND u.agent_id = ? AND UNIX_TIMESTAMP(o.created_at) > ?", [$agent_id, $cleared_spot]);
|
$active_spot = getCount($db, "SELECT COUNT(*) FROM spot_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 0 AND u.agent_id = ?", [$agent_id]);
|
||||||
$active_contract = getCount($db, "SELECT COUNT(*) FROM contract_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'open' AND u.agent_id = ? AND UNIX_TIMESTAMP(o.created_at) > ?", [$agent_id, $cleared_contract]);
|
$active_contract = getCount($db, "SELECT COUNT(*) FROM contract_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'open' AND u.agent_id = ?", [$agent_id]);
|
||||||
$new_messages = getCount($db, "SELECT COUNT(*) FROM messages m JOIN users u ON m.user_id = u.id WHERE m.sender = 'user' AND u.agent_id = ? AND UNIX_TIMESTAMP(m.created_at) > ?", [$agent_id, $cleared_messages]);
|
$new_messages = getCount($db, "SELECT COUNT(*) FROM messages m JOIN users u ON m.user_id = u.id WHERE m.sender = 'user' AND m.is_read = 0 AND u.agent_id = ?", [$agent_id]);
|
||||||
$new_registrations = getCount($db, "SELECT COUNT(*) FROM users WHERE agent_id = ? AND UNIX_TIMESTAMP(created_at) > ?", [$agent_id, $cleared_users]);
|
$new_registrations = getCount($db, "SELECT COUNT(*) FROM users WHERE agent_id = ? AND created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)", [$agent_id]);
|
||||||
} else {
|
} else {
|
||||||
$pending_recharge = getCount($db, "SELECT COUNT(*) FROM finance_requests WHERE type = 'recharge' AND status NOT IN ('3', '4') AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_recharge]);
|
$pending_recharge = getCount($db, "SELECT COUNT(*) FROM finance_requests WHERE type = 'recharge' AND status = '0'", []);
|
||||||
$pending_withdrawal = getCount($db, "SELECT COUNT(*) FROM finance_requests WHERE type = 'withdrawal' AND status NOT IN ('3', '4') AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_recharge]);
|
$pending_withdrawal = getCount($db, "SELECT COUNT(*) FROM finance_requests WHERE type = 'withdrawal' AND status = '0'", []);
|
||||||
$pending_kyc = getCount($db, "SELECT COUNT(*) FROM users WHERE kyc_status = 1 AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_kyc]);
|
$pending_kyc = getCount($db, "SELECT COUNT(*) FROM users WHERE kyc_status = 1", []);
|
||||||
$active_binary = getCount($db, "SELECT COUNT(*) FROM binary_orders WHERE status = 'pending' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_binary]);
|
$active_binary = getCount($db, "SELECT COUNT(*) FROM binary_orders WHERE status = 'pending'", []);
|
||||||
$active_spot = getCount($db, "SELECT COUNT(*) FROM spot_orders WHERE status = 0 AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_spot]);
|
$active_spot = getCount($db, "SELECT COUNT(*) FROM spot_orders WHERE status = 0", []);
|
||||||
$active_contract = getCount($db, "SELECT COUNT(*) FROM contract_orders WHERE status = 'open' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_contract]);
|
$active_contract = getCount($db, "SELECT COUNT(*) FROM contract_orders WHERE status = 'open'", []);
|
||||||
$new_messages = getCount($db, "SELECT COUNT(*) FROM messages WHERE sender = 'user' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_messages]);
|
$new_messages = getCount($db, "SELECT COUNT(*) FROM messages WHERE sender = 'user' AND is_read = 0", []);
|
||||||
$new_registrations = getCount($db, "SELECT COUNT(*) FROM users WHERE UNIX_TIMESTAMP(created_at) > ?", [$cleared_users]);
|
$new_registrations = getCount($db, "SELECT COUNT(*) FROM users WHERE created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)", []);
|
||||||
}
|
}
|
||||||
|
|
||||||
$total = $pending_recharge + $pending_withdrawal + $pending_kyc + $active_binary + $active_spot + $active_contract + $new_messages + $new_registrations;
|
$total = $pending_recharge + $pending_withdrawal + $pending_kyc + $active_binary + $active_spot + $active_contract + $new_messages;
|
||||||
$sound_trigger_count = $pending_recharge + $pending_withdrawal + $new_messages + $new_registrations;
|
$sound_trigger_count = $total; // Trigger sound for any pending action
|
||||||
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'success' => true,
|
'success' => true,
|
||||||
|
|||||||
36
api/chat.php
36
api/chat.php
@ -107,6 +107,10 @@ if ($action === 'get_messages') {
|
|||||||
if (isset($_SESSION['admin_id'])) {
|
if (isset($_SESSION['admin_id'])) {
|
||||||
$stmt = db()->prepare("SELECT * FROM messages WHERE (user_id = ? AND user_id != 0) OR (session_id = ? AND session_id != '') OR (ip_address = ? AND ip_address != '' AND session_id = '') ORDER BY created_at ASC");
|
$stmt = db()->prepare("SELECT * FROM messages WHERE (user_id = ? AND user_id != 0) OR (session_id = ? AND session_id != '') OR (ip_address = ? AND ip_address != '' AND session_id = '') ORDER BY created_at ASC");
|
||||||
$stmt->execute([$target_user_id, $target_sid, $target_ip]);
|
$stmt->execute([$target_user_id, $target_sid, $target_ip]);
|
||||||
|
|
||||||
|
// Mark as read
|
||||||
|
$stmt_read = db()->prepare("UPDATE messages SET is_read = 1 WHERE sender = 'user' AND ((user_id = ? AND user_id != 0) OR (session_id = ? AND session_id != '') OR (ip_address = ? AND ip_address != '' AND session_id = ''))");
|
||||||
|
$stmt_read->execute([$target_user_id, $target_sid, $target_ip]);
|
||||||
} else {
|
} else {
|
||||||
// User requesting their own messages
|
// User requesting their own messages
|
||||||
$user_id = (int)($_SESSION['user_id'] ?? 0);
|
$user_id = (int)($_SESSION['user_id'] ?? 0);
|
||||||
@ -157,6 +161,19 @@ if ($action === 'send_message') {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($action === 'mark_read') {
|
||||||
|
if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized']));
|
||||||
|
$user_id = (int)($_POST['user_id'] ?? 0);
|
||||||
|
$ip = $_POST['ip_address'] ?? '';
|
||||||
|
$sid = $_POST['session_id'] ?? '';
|
||||||
|
if ($ip === '---') $ip = '';
|
||||||
|
|
||||||
|
$stmt = db()->prepare("UPDATE messages SET is_read = 1 WHERE sender = 'user' AND is_read = 0 AND ((user_id = ? AND user_id != 0) OR (session_id = ? AND session_id != '') OR (ip_address = ? AND ip_address != '' AND session_id = ''))");
|
||||||
|
$stmt->execute([$user_id, $sid, $ip]);
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ($action === 'admin_send') {
|
if ($action === 'admin_send') {
|
||||||
if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized']));
|
if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized']));
|
||||||
|
|
||||||
@ -237,7 +254,8 @@ if ($action === 'admin_get_all') {
|
|||||||
SUBSTRING_INDEX(GROUP_CONCAT(effective_sid ORDER BY last_activity DESC SEPARATOR '|'), '|', 1) as effective_sid,
|
SUBSTRING_INDEX(GROUP_CONCAT(effective_sid ORDER BY last_activity DESC SEPARATOR '|'), '|', 1) as effective_sid,
|
||||||
MAX(last_activity) as last_activity,
|
MAX(last_activity) as last_activity,
|
||||||
MAX(user_time) as user_time,
|
MAX(user_time) as user_time,
|
||||||
MAX(has_recharge) as has_recharge
|
MAX(has_recharge) as has_recharge,
|
||||||
|
SUM(is_unread) as unread_count
|
||||||
FROM (
|
FROM (
|
||||||
SELECT
|
SELECT
|
||||||
COALESCE(NULLIF(user_id, 0), (SELECT id FROM users WHERE registration_ip = m.ip_address AND m.ip_address != '---' AND m.ip_address != '' LIMIT 1), 0) as final_user_id,
|
COALESCE(NULLIF(user_id, 0), (SELECT id FROM users WHERE registration_ip = m.ip_address AND m.ip_address != '---' AND m.ip_address != '' LIMIT 1), 0) as final_user_id,
|
||||||
@ -245,7 +263,8 @@ if ($action === 'admin_get_all') {
|
|||||||
IFNULL(session_id, '') as effective_sid,
|
IFNULL(session_id, '') as effective_sid,
|
||||||
created_at as last_activity,
|
created_at as last_activity,
|
||||||
NULL as user_time,
|
NULL as user_time,
|
||||||
0 as has_recharge
|
0 as has_recharge,
|
||||||
|
CASE WHEN sender = 'user' AND is_read = 0 THEN 1 ELSE 0 END as is_unread
|
||||||
FROM messages m
|
FROM messages m
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT
|
SELECT
|
||||||
@ -254,7 +273,8 @@ if ($action === 'admin_get_all') {
|
|||||||
IFNULL(session_id, '') as effective_sid,
|
IFNULL(session_id, '') as effective_sid,
|
||||||
last_ping as last_activity,
|
last_ping as last_activity,
|
||||||
user_time,
|
user_time,
|
||||||
0 as has_recharge
|
0 as has_recharge,
|
||||||
|
0 as is_unread
|
||||||
FROM chat_visitors cv
|
FROM chat_visitors cv
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT
|
SELECT
|
||||||
@ -263,7 +283,8 @@ if ($action === 'admin_get_all') {
|
|||||||
'' as effective_sid,
|
'' as effective_sid,
|
||||||
created_at as last_activity,
|
created_at as last_activity,
|
||||||
NULL as user_time,
|
NULL as user_time,
|
||||||
1 as has_recharge
|
1 as has_recharge,
|
||||||
|
0 as is_unread
|
||||||
FROM finance_requests fr
|
FROM finance_requests fr
|
||||||
) t1
|
) t1
|
||||||
GROUP BY final_user_id, (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)
|
GROUP BY final_user_id, (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)
|
||||||
@ -284,7 +305,12 @@ if ($action === 'admin_get_all') {
|
|||||||
LEFT JOIN chat_remarks r ON (v.final_user_id = r.user_id AND (v.final_user_id != 0 OR (v.effective_sid != '' AND v.effective_sid = r.session_id) OR (v.effective_sid = '' AND v.effective_ip = r.ip_address)))
|
LEFT JOIN chat_remarks r ON (v.final_user_id = r.user_id AND (v.final_user_id != 0 OR (v.effective_sid != '' AND v.effective_sid = r.session_id) OR (v.effective_sid = '' AND v.effective_ip = r.ip_address)))
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
");
|
");
|
||||||
echo json_encode($stmt->fetchAll());
|
$results = $stmt->fetchAll();
|
||||||
|
// Convert unread_count to int
|
||||||
|
foreach ($results as &$row) {
|
||||||
|
$row['unread_count'] = (int)$row['unread_count'];
|
||||||
|
}
|
||||||
|
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()]);
|
echo json_encode(['error' => $e->getMessage()]);
|
||||||
|
|||||||
@ -54,3 +54,50 @@ if (!function_exists('getSetting')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure database schema is up to date (Automatic Migration)
|
||||||
|
function ensureSchema() {
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
|
||||||
|
// --- finance_requests table ---
|
||||||
|
$stmt = $db->query("DESCRIBE finance_requests");
|
||||||
|
$columns = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
$finance_needed = [
|
||||||
|
'account_bank' => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
'account_name' => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
'account_number' => "VARCHAR(255) DEFAULT NULL",
|
||||||
|
'fiat_amount' => "DECIMAL(20,8) DEFAULT 0",
|
||||||
|
'fiat_currency' => "VARCHAR(10) DEFAULT NULL",
|
||||||
|
'ip_address' => "VARCHAR(45) DEFAULT NULL",
|
||||||
|
'payment_method' => "VARCHAR(100) DEFAULT NULL",
|
||||||
|
'payment_details' => "TEXT DEFAULT NULL"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($finance_needed as $col => $type) {
|
||||||
|
if (!in_array($col, $columns)) {
|
||||||
|
$db->exec("ALTER TABLE finance_requests ADD COLUMN $col $type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- transactions table ---
|
||||||
|
$stmt = $db->query("DESCRIBE transactions");
|
||||||
|
$columns = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
$trans_needed = [
|
||||||
|
'ip_address' => "VARCHAR(45) DEFAULT NULL",
|
||||||
|
'status' => "VARCHAR(20) DEFAULT '0'"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($trans_needed as $col => $type) {
|
||||||
|
if (!in_array($col, $columns)) {
|
||||||
|
$db->exec("ALTER TABLE transactions ADD COLUMN $col $type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Silently fail or log to a file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ensureSchema();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user