323 lines
17 KiB
PHP
323 lines
17 KiB
PHP
<?php
|
|
include 'header.php';
|
|
if (!isset($_SESSION['user_id'])) {
|
|
echo "<script>location.href='login.php';</script>";
|
|
exit;
|
|
}
|
|
|
|
$user_id = $_SESSION['user_id'];
|
|
$pdo = db();
|
|
|
|
// Fetch user info
|
|
$stmt = $pdo->prepare("SELECT uid, username, last_ip FROM users WHERE id = ?");
|
|
$stmt->execute([$user_id]);
|
|
$user = $stmt->fetch();
|
|
|
|
// Check if there's an active deposit/withdrawal process
|
|
$stmt = $pdo->prepare("SELECT * FROM fiat_orders WHERE user_id = ? AND status IN ('matching', 'matched', 'paid') ORDER BY id DESC LIMIT 1");
|
|
$stmt->execute([$user_id]);
|
|
$active_order = $stmt->fetch();
|
|
|
|
$is_locked = (bool)$active_order;
|
|
|
|
// Action to complete transfer/submission
|
|
if (isset($_GET['action']) && $_GET['action'] === 'complete_order' && $active_order) {
|
|
$stmt = $pdo->prepare("UPDATE fiat_orders SET status = 'paid' WHERE id = ?");
|
|
$stmt->execute([$active_order['id']]);
|
|
|
|
$type_text = ($active_order['order_type'] === 'deposit') ? __('nav_deposit') : __('nav_withdraw');
|
|
$msg = "✅ " . __('confirm_transfer') . ", $type_text " . __('paid_waiting_tip');
|
|
$stmt = $pdo->prepare("INSERT INTO messages (user_id, sender, message) VALUES (?, 'user', ?)");
|
|
$stmt->execute([$user_id, $msg]);
|
|
|
|
header("Location: chat.php");
|
|
exit;
|
|
}
|
|
|
|
// Fetch greeting message
|
|
$stmt = $pdo->prepare("SELECT value FROM settings WHERE name = 'chat_greeting'");
|
|
$stmt->execute();
|
|
$greeting = $stmt->fetchColumn();
|
|
if (!$greeting) {
|
|
$greeting = ($lang == 'zh') ? '您好!欢迎咨询 NovaEx 官方客服,请问有什么可以帮您?如果是充值咨询,请提供您的充值金额和币种。' : 'Hello! Welcome to NovaEx official customer service. How can we help you today? For deposit inquiries, please provide your amount and currency.';
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['message'])) {
|
|
$msg = trim($_POST['message']);
|
|
if ($msg !== '') {
|
|
$stmt = $pdo->prepare("INSERT INTO messages (user_id, sender, message) VALUES (?, 'user', ?)");
|
|
$stmt->execute([$user_id, $msg]);
|
|
echo json_encode(['success' => true]);
|
|
}
|
|
exit;
|
|
}
|
|
?>
|
|
|
|
<style>
|
|
#chat-box::-webkit-scrollbar { width: 6px; }
|
|
#chat-box::-webkit-scrollbar-track { background: transparent; }
|
|
#chat-box::-webkit-scrollbar-thumb { background: #2b3139; border-radius: 10px; }
|
|
#chat-box { flex: 1; overflow-y: auto; padding: 25px; display: flex; flex-direction: column; gap: 20px; background: #161a1e; scroll-behavior: smooth; }
|
|
|
|
.msg-container { display: flex; flex-direction: column; transition: all 0.3s ease; }
|
|
.msg-content { max-width: 75%; padding: 12px 18px; border-radius: 18px; font-size: 14px; line-height: 1.6; position: relative; }
|
|
|
|
.account-modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; max-width: 450px; background: #1e2329; border-radius: 24px; border: 1px solid var(--primary-color); z-index: 10001; padding: 30px; box-shadow: 0 20px 50px rgba(0,0,0,0.8); display: none; }
|
|
.modal-backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 10000; display: none; }
|
|
|
|
.status-bar { background: rgba(240,185,11,0.1); border: 1px solid var(--primary-color); padding: 15px 25px; border-radius: 12px; margin-bottom: 15px; display: flex; align-items: center; justify-content: space-between; color: var(--primary-color); }
|
|
|
|
#image-upload-btn:hover { background: #3b424d !important; color: #fcd535 !important; }
|
|
#image-upload-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
</style>
|
|
|
|
<!-- Account Details Modal -->
|
|
<div id="acc-backdrop" class="modal-backdrop"></div>
|
|
<div id="acc-modal" class="account-modal">
|
|
<div style="text-align: center; margin-bottom: 25px;">
|
|
<div style="width: 60px; height: 60px; background: rgba(240,185,11,0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: var(--primary-color); margin: 0 auto 15px; font-size: 24px;">
|
|
<i class="fas fa-university"></i>
|
|
</div>
|
|
<h3 style="margin: 0; color: white;" id="modal-title"><?php echo __('matched_status'); ?></h3>
|
|
<p style="color: var(--text-muted); font-size: 14px; margin-top: 5px;" id="modal-tip"><?php echo __('matched_info_tip'); ?></p>
|
|
</div>
|
|
<div id="acc-info" style="background: #161a1e; padding: 20px; border-radius: 16px; color: white; font-size: 14px; line-height: 2; border: 1px solid #2b3139; margin-bottom: 25px;">
|
|
<!-- Filled by JS -->
|
|
</div>
|
|
<button onclick="closeAccModal()" class="btn-primary" style="width: 100%; padding: 15px; border-radius: 12px; font-weight: 800;"><?php echo __('confirm'); ?></button>
|
|
</div>
|
|
|
|
<div id="chat-container" class="container" style="max-width: 850px; margin: 30px auto; padding: 0; height: calc(100vh - 200px); min-height: 500px;">
|
|
<?php if ($is_locked): ?>
|
|
<div class="status-bar">
|
|
<div style="display: flex; align-items: center; gap: 15px;">
|
|
<i class="fas fa-lock"></i>
|
|
<div>
|
|
<div style="font-size: 14px; font-weight: 800;"><?php echo ($active_order['order_type'] === 'deposit') ? __('nav_deposit') : __('nav_withdraw'); ?></div>
|
|
<div style="font-size: 12px; opacity: 0.8;"><?php
|
|
if ($active_order['status'] === 'matching') echo __('matching_status') . '...';
|
|
elseif ($active_order['status'] === 'matched') echo ($active_order['order_type'] === 'deposit') ? __('matched_info_tip') : __('withdraw_info_tip');
|
|
elseif ($active_order['status'] === 'paid') echo __('paid_waiting_tip');
|
|
?></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 10px;">
|
|
<?php if ($active_order['status'] === 'matched'): ?>
|
|
<button onclick="showCurrentAccInfo()" class="btn-primary" style="padding: 8px 15px; font-size: 12px; border-radius: 8px; background: #2b3139; color: white; border: 1px solid #3b424d;">
|
|
<?php echo ($active_order['order_type'] === 'deposit') ? __('view_account') : __('view_withdraw_format'); ?>
|
|
</button>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($active_order['status'] === 'matched'): ?>
|
|
<button onclick="window.location.href='?action=complete_order'" class="btn-primary" style="padding: 8px 15px; font-size: 12px; border-radius: 8px;">
|
|
<?php echo ($active_order['order_type'] === 'deposit') ? __('complete_transfer_btn') : __('confirm'); ?>
|
|
</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div id="chat-card" class="card" style="background: #1e2329; border: 1px solid #2b3139; border-radius: 20px; display: flex; flex-direction: column; height: 100%; box-shadow: 0 10px 30px rgba(0,0,0,0.3); overflow: hidden;">
|
|
<!-- Header -->
|
|
<div style="padding: 20px 25px; border-bottom: 1px solid #2b3139; display: flex; align-items: center; justify-content: space-between; background: #1e2329;">
|
|
<div style="display: flex; align-items: center; gap: 15px;">
|
|
<div style="width: 45px; height: 45px; background: #f0b90b; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: black;">
|
|
<i class="fas fa-headset fa-lg"></i>
|
|
</div>
|
|
<div>
|
|
<h3 style="margin: 0; font-size: 18px; color: white;"><?php echo __('support_online'); ?></h3>
|
|
<div style="display: flex; align-items: center; gap: 5px; font-size: 12px; color: #00c087;">
|
|
<span style="width: 8px; height: 8px; background: #00c087; border-radius: 50%; display: inline-block;"></span> 24/7 <?php echo ($lang == 'zh' ? '全天候在线' : 'Always Online'); ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style="text-align: right; font-size: 12px; color: #848e9c;">
|
|
<div>UID: <?php echo htmlspecialchars($user['uid']); ?></div>
|
|
<div style="font-size: 10px; opacity: 0.7;">IP: <?php echo htmlspecialchars($user['last_ip']); ?></div>
|
|
<a href="index.php" style="color: var(--primary-color); text-decoration: none; display: <?php echo $is_locked ? 'none' : 'block'; ?>; margin-top: 5px;"><i class="fas fa-times"></i> <?php echo __('cancel'); ?></a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Chat Body -->
|
|
<div id="chat-box">
|
|
<div style="text-align: center; color: #848e9c; padding: 20px;">Connecting...</div>
|
|
</div>
|
|
|
|
<!-- Input Area -->
|
|
<div style="padding: 20px; background: #1e2329; border-top: 1px solid #2b3139;">
|
|
<form id="chat-form" style="display: flex; gap: 12px; align-items: center;">
|
|
<button type="button" id="image-upload-btn" onclick="document.getElementById('image-input').click()" style="background: #2b3139; border: 1px solid #3b424d; color: #f0b90b; width: 45px; height: 45px; border-radius: 12px; cursor: pointer; flex-shrink: 0; display: flex; align-items: center; justify-content: center; transition: all 0.2s;">
|
|
<i class="fas fa-plus"></i>
|
|
</button>
|
|
<input type="file" id="image-input" accept="image/*" style="display: none;" onchange="uploadImage(this)">
|
|
|
|
<input type="text" id="chat-input" placeholder="<?php echo __('type_message'); ?>"
|
|
style="flex: 1; background: #161a1e; border: 1px solid #2b3139; border-radius: 12px; padding: 14px 20px; color: white; outline: none; font-size: 14px;" autocomplete="off">
|
|
|
|
<button type="submit" style="background: #f0b90b; border: none; color: black; width: 50px; height: 50px; border-radius: 12px; cursor: pointer; display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
|
<i class="fas fa-paper-plane fa-lg"></i>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($is_locked): ?>
|
|
<script>
|
|
window.onbeforeunload = function() {
|
|
return "<?php echo ($lang == 'zh' ? '您的业务流程尚未完成,请勿离开此页面。' : 'Your transaction is not complete. Please stay on this page.'); ?>";
|
|
};
|
|
document.querySelector('nav')?.style.display = 'none';
|
|
document.querySelector('footer')?.style.display = 'none';
|
|
|
|
history.pushState(null, null, location.href);
|
|
window.onpopstate = function() {
|
|
history.pushState(null, null, location.href);
|
|
};
|
|
</script>
|
|
<?php endif; ?>
|
|
|
|
<script>
|
|
const chatBox = document.getElementById('chat-box');
|
|
const chatForm = document.getElementById('chat-form');
|
|
const chatInput = document.getElementById('chat-input');
|
|
const uploadBtn = document.getElementById('image-upload-btn');
|
|
let lastStatus = '<?php echo $active_order['status'] ?? ''; ?>';
|
|
let currentBankAccountInfo = `<?php echo addslashes($active_order['bank_account_info'] ?? ''); ?>`;
|
|
const greeting = `<?php echo addslashes($greeting); ?>`;
|
|
|
|
async function loadMessages() {
|
|
try {
|
|
const resp = await fetch('api/get_messages.php');
|
|
const res = await resp.json();
|
|
if (res.success) {
|
|
const newMessages = res.data;
|
|
if (newMessages.length === 0) {
|
|
chatBox.innerHTML = `
|
|
<div style="display: flex; flex-direction: column; align-items: flex-start;">
|
|
<div class="msg-content" style="background: #2b3139; color: white; border-bottom-left-radius: 4px; border: 1px solid #3b424d;">
|
|
${greeting.replace(/\n/g, '<br>')}
|
|
</div>
|
|
<span style="font-size: 10px; color: #5e6673; margin-top: 6px;">Support</span>
|
|
</div>
|
|
`;
|
|
} else {
|
|
let html = '';
|
|
newMessages.forEach(m => {
|
|
const isUser = m.sender === 'user';
|
|
html += `
|
|
<div class="msg-container" style="align-items: ${isUser ? 'flex-end' : 'flex-start'};">
|
|
<div class="msg-content" style="${isUser ? 'background: #f0b90b; color: black; border-bottom-right-radius: 4px;' : 'background: #2b3139; color: white; border-bottom-left-radius: 4px; border: 1px solid #3b424d;'} ">
|
|
${m.type === 'image' ? `<img src="${m.message}" style="max-width:100%; border-radius:8px; cursor:pointer;" onclick="window.open(this.src)">` : m.message.replace(/\n/g, '<br>')}
|
|
</div>
|
|
<span style="font-size: 10px; color: #5e6673; margin-top: 6px;">${new Date(m.created_at).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</span>
|
|
</div>
|
|
`;
|
|
});
|
|
|
|
const isAtBottom = chatBox.scrollHeight - chatBox.scrollTop <= chatBox.clientHeight + 100;
|
|
chatBox.innerHTML = html;
|
|
if (isAtBottom) chatBox.scrollTop = chatBox.scrollHeight;
|
|
}
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
async function checkOrderStatus() {
|
|
try {
|
|
const resp = await fetch('api/check_order_status.php');
|
|
const res = await resp.json();
|
|
if (res.success && res.order) {
|
|
currentBankAccountInfo = res.order.bank_account_info;
|
|
if (res.order.status !== lastStatus) {
|
|
const title = res.order.order_type === 'deposit' ? '<?php echo __('matched_status'); ?>' : '<?php echo __('withdraw_format_title'); ?>';
|
|
const tip = res.order.order_type === 'deposit' ? '<?php echo __('matched_info_tip'); ?>' : '<?php echo __('withdraw_info_tip'); ?>';
|
|
showAccModal(title, tip, res.order.bank_account_info);
|
|
} else if (res.order.status === 'completed' || res.order.status === 'rejected') {
|
|
alert(res.order.status === 'completed' ? "Success!" : "Request rejected.");
|
|
window.onbeforeunload = null;
|
|
location.href = 'profile.php';
|
|
}
|
|
lastStatus = res.order.status;
|
|
}
|
|
} else if (res.success && !res.order && lastStatus !== '') {
|
|
window.onbeforeunload = null;
|
|
location.href = 'profile.php';
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
function showAccModal(title, tip, info) {
|
|
if (!info) return;
|
|
document.getElementById('modal-title').innerText = title;
|
|
document.getElementById('modal-tip').innerText = tip;
|
|
document.getElementById('acc-info').innerHTML = info.replace(/\n/g, '<br>');
|
|
document.getElementById('acc-backdrop').style.display = 'block';
|
|
document.getElementById('acc-modal').style.display = 'block';
|
|
}
|
|
|
|
function showCurrentAccInfo() {
|
|
const orderType = '<?php echo $active_order['order_type'] ?? ''; ?>';
|
|
const title = orderType === 'deposit' ? '<?php echo __('view_account'); ?>' : '<?php echo __('view_withdraw_format'); ?>';
|
|
const tip = orderType === 'deposit' ? '<?php echo __('matched_info_tip'); ?>' : '<?php echo __('withdraw_info_tip'); ?>';
|
|
showAccModal(title, tip, currentBankAccountInfo);
|
|
}
|
|
|
|
function closeAccModal() {
|
|
document.getElementById('acc-backdrop').style.display = 'none';
|
|
document.getElementById('acc-modal').style.display = 'none';
|
|
}
|
|
|
|
chatForm.onsubmit = async (e) => {
|
|
e.preventDefault();
|
|
const msg = chatInput.value.trim();
|
|
if (!msg) return;
|
|
|
|
chatInput.value = '';
|
|
const formData = new FormData();
|
|
formData.append('message', msg);
|
|
|
|
await fetch('chat.php', { method: 'POST', body: formData });
|
|
loadMessages();
|
|
};
|
|
|
|
function uploadImage(input) {
|
|
if (!input.files || !input.files[0]) return;
|
|
const formData = new FormData();
|
|
formData.append('image', input.files[0]);
|
|
|
|
uploadBtn.disabled = true;
|
|
uploadBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
|
|
|
|
fetch('api/upload_chat_image.php', { method: 'POST', body: formData })
|
|
.then(res => res.json())
|
|
.then(res => {
|
|
if (res.success) {
|
|
loadMessages();
|
|
} else {
|
|
alert(res.error || 'Upload failed');
|
|
}
|
|
})
|
|
.finally(() => {
|
|
uploadBtn.disabled = false;
|
|
uploadBtn.innerHTML = '<i class="fas fa-plus"></i>';
|
|
input.value = '';
|
|
});
|
|
}
|
|
|
|
window.onload = () => {
|
|
const orderType = '<?php echo $active_order['order_type'] ?? ''; ?>';
|
|
if (lastStatus === 'matched' && currentBankAccountInfo) {
|
|
const title = orderType === 'deposit' ? '<?php echo __('matched_status'); ?>' : '<?php echo __('withdraw_format_title'); ?>';
|
|
const tip = orderType === 'deposit' ? '<?php echo __('matched_info_tip'); ?>' : '<?php echo __('withdraw_info_tip'); ?>';
|
|
showAccModal(title, tip, currentBankAccountInfo);
|
|
}
|
|
};
|
|
|
|
loadMessages();
|
|
setInterval(loadMessages, 3000);
|
|
setInterval(checkOrderStatus, 3000);
|
|
</script>
|
|
|
|
<?php include 'footer.php'; ?>
|