38350-vm/matching.php
2026-02-11 11:52:19 +00:00

375 lines
23 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
include 'header.php';
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
require_once 'db/config.php';
$user_id = $_SESSION['user_id'];
// Handle initial order creation from deposit.php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['amount'])) {
$amount = $_POST['amount'];
$type = $_POST['type'] ?? 'fiat';
$currency = $_POST['currency'] ?? 'USDT';
// Set expiration to 30 minutes from now
$expires_at = date('Y-m-d H:i:s', strtotime('+30 minutes'));
// Create order in fiat_orders table
$stmt = db()->prepare("INSERT INTO fiat_orders (user_id, amount, currency, status, expires_at, created_at) VALUES (?, ?, ?, 'matching', ?, CURRENT_TIMESTAMP)");
$stmt->execute([$user_id, $amount, $currency, $expires_at]);
$order_id = db()->lastInsertId();
// Notify CS via messages table (Admin notification)
$msg = "[SYSTEM] 用户 {$_SESSION['email']} (UID: {$_SESSION['uid']}) 正在发起充值匹配: $amount $currency。请尽快提供收款账户详情。";
$stmt = db()->prepare("INSERT INTO messages (user_id, sender, message) VALUES (?, 'user', ?)");
$stmt->execute([$user_id, $msg]);
header("Location: matching.php?order_id=" . $order_id);
exit;
}
$order_id = $_GET['order_id'] ?? null;
if (!$order_id) {
header("Location: deposit.php");
exit;
}
// Fetch order
$stmt = db()->prepare("SELECT * FROM fiat_orders WHERE id = ? AND user_id = ?");
$stmt->execute([$order_id, $user_id]);
$order = $stmt->fetch();
if (!$order) {
header("Location: deposit.php");
exit;
}
// Handle Proof Upload
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['proof'])) {
$file = $_FILES['proof'];
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
$filename = 'proof_' . $order_id . '_' . time() . '.' . $ext;
$target = 'assets/images/proofs/' . $filename;
if (!is_dir('assets/images/proofs/')) mkdir('assets/images/proofs/', 0775, true);
if (move_uploaded_file($file['tmp_name'], $target)) {
$stmt = db()->prepare("UPDATE fiat_orders SET proof_image = ?, status = 'submitting' WHERE id = ?");
$stmt->execute(['assets/images/proofs/' . $filename, $order_id]);
// Notify admin
$msg = "[SYSTEM] 用户已上传支付凭证 (订单 #$order_id)。请进入管理后台核对入账。";
$stmt = db()->prepare("INSERT INTO messages (user_id, sender, message) VALUES (?, 'user', ?)");
$stmt->execute([$user_id, $msg]);
header("Location: matching.php?order_id=" . $order_id);
exit;
}
}
// Fetch messages for the chat portion
$stmt = db()->prepare("SELECT * FROM messages WHERE user_id = ? AND message NOT LIKE '[SYSTEM]%' ORDER BY created_at ASC");
$stmt->execute([$user_id]);
$messages = $stmt->fetchAll();
?>
<main style="padding: 40px 20px; background: #0b0e11; min-height: calc(100vh - 64px); color: white;">
<div style="max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: 1fr 380px; gap: 30px;">
<!-- Left Side: Matching & Instructions -->
<div style="background: #161a1e; padding: 40px; border-radius: 24px; border: 1px solid #2b3139; position: relative; overflow: hidden;">
<?php if ($order['status'] === 'matching' && !$order['bank_account_info']): ?>
<!-- Phase 1: Matching Animation -->
<div id="matching-container" style="text-align: center; padding: 60px 0;">
<div style="position: relative; width: 120px; height: 120px; margin: 0 auto 40px;">
<div class="loader-ring" style="width: 100%; height: 100%; border: 4px solid rgba(79, 172, 254, 0.1); border-top-color: var(--primary-color); border-radius: 50%; animation: spin 1s linear infinite;"></div>
<i class="fas fa-user-shield" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 40px; color: var(--primary-color);"></i>
</div>
<h2 style="font-size: 2.2rem; font-weight: 800; margin-bottom: 20px; background: linear-gradient(90deg, #fff, var(--primary-color)); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">正在为你匹配充值账户请稍等...</h2>
<p style="color: #848e9c; font-size: 1.1rem; max-width: 500px; margin: 0 auto 40px; line-height: 1.6;">
我们正在为您匹配最安全、快捷的本地支付通道。匹配成功后,请在规定时间内完成转账。
</p>
<div style="max-width: 300px; margin: 0 auto; background: rgba(79, 172, 254, 0.05); padding: 30px; border-radius: 20px; border: 1px dashed var(--primary-color);">
<div id="countdown" style="font-size: 3rem; font-weight: 900; color: var(--primary-color); font-family: 'Roboto Mono', monospace;">30:00</div>
<div style="font-size: 13px; color: #848e9c; margin-top: 10px; font-weight: bold;">匹配倒计时 / Matching Countdown</div>
</div>
<div style="margin-top: 60px; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; text-align: left;">
<div style="background: #0b0e11; padding: 20px; border-radius: 16px;">
<i class="fas fa-lock" style="color: #00c087; margin-bottom: 10px;"></i>
<div style="font-weight: bold; font-size: 14px; margin-bottom: 5px;">加密保护</div>
<div style="font-size: 12px; color: #5e6673;">所有交易信息经过端到端加密处理,保障您的资金隐私。</div>
</div>
<div style="background: #0b0e11; padding: 20px; border-radius: 16px;">
<i class="fas fa-bolt" style="color: #f0b90b; margin-bottom: 10px;"></i>
<div style="font-weight: bold; font-size: 14px; margin-bottom: 5px;">快速响应</div>
<div style="font-size: 12px; color: #5e6673;">客服系统 7x24 小时在线,实时处理您的充值匹配请求。</div>
</div>
</div>
</div>
<?php elseif ($order['bank_account_info'] && $order['status'] !== 'submitting' && $order['status'] !== 'completed'): ?>
<!-- Phase 2: Matched Account Details -->
<div>
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 30px; border-bottom: 1px solid #2b3139; padding-bottom: 25px;">
<div style="display: flex; align-items: center; gap: 15px;">
<div style="width: 50px; height: 50px; background: rgba(0, 192, 135, 0.1); border-radius: 12px; display: flex; align-items: center; justify-content: center; color: #00c087; font-size: 20px;">
<i class="fas fa-check-double"></i>
</div>
<div>
<h2 style="margin: 0; font-size: 1.5rem;">账户匹配成功 / Matched</h2>
<p style="margin: 5px 0 0; color: #848e9c; font-size: 13px;">请按照以下信息进行转账支付</p>
</div>
</div>
<div id="countdown" style="font-size: 1.5rem; font-weight: bold; color: #f0b90b; background: rgba(240, 185, 11, 0.1); padding: 5px 15px; border-radius: 8px;">30:00</div>
</div>
<div style="background: #0b0e11; padding: 35px; border-radius: 20px; border: 2px solid #2b3139; margin-bottom: 35px; position: relative;">
<div style="position: absolute; top: 15px; right: 20px; font-size: 10px; color: #5e6673; letter-spacing: 2px;">SECURE CHANNEL</div>
<div style="color: var(--primary-color); font-size: 12px; margin-bottom: 20px; font-weight: 800; display: flex; align-items: center; gap: 8px;">
<i class="fas fa-info-circle"></i> 收款方详情 / RECEIVING DETAILS
</div>
<div style="font-size: 1.3rem; line-height: 2.2; font-family: 'Roboto Mono', monospace; color: #EAECEF;">
<?php echo nl2br(htmlspecialchars($order['bank_account_info'])); ?>
</div>
<div style="margin-top: 25px; padding-top: 25px; border-top: 1px solid #2b3139; display: flex; justify-content: space-between; align-items: center;">
<span style="color: #848e9c; font-size: 14px;">应付金额 / Payable Amount:</span>
<span style="font-weight: 900; font-size: 2rem; color: #f0b90b;"><?php echo number_format($order['amount'], 2); ?> <span style="font-size: 1rem;"><?php echo $order['currency']; ?></span></span>
</div>
<div style="margin-top: 15px; background: rgba(240, 185, 11, 0.05); padding: 10px; border-radius: 8px; font-size: 11px; color: #f0b90b; text-align: center;">
<i class="fas fa-exclamation-triangle"></i> 请确保转账金额与上述金额完全一致,否则将无法入账。
</div>
</div>
<!-- Enhanced Instructions & Safety Tips -->
<div style="margin-bottom: 40px;">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 25px;">
<div>
<h4 style="margin-bottom: 15px; display: flex; align-items: center; gap: 10px; color: white;"><i class="fas fa-list-ol" style="color: var(--primary-color);"></i> 转账说明 / Instructions</h4>
<ul style="margin: 0; padding-left: 20px; font-size: 13px; color: #848e9c; line-height: 2;">
<li>使用本人实名认证的银行账户进行转账。</li>
<li><b style="color: #f0b90b;">严禁备注</b>任何敏感字眼数字货币、USDT、NovaEx等。</li>
<li>匹配账户仅限单次使用,请勿重复转账或保存账户。</li>
<li>转账完成后,请务必保留电子回单或转账成功截图。</li>
</ul>
</div>
<div>
<h4 style="margin-bottom: 15px; display: flex; align-items: center; gap: 10px; color: white;"><i class="fas fa-user-shield" style="color: #00c087;"></i> 注意事项 / Precautions</h4>
<ul style="margin: 0; padding-left: 20px; font-size: 13px; color: #848e9c; line-height: 2;">
<li>NovaEx 官方客服不会通过私人社交账号向您索要资金。</li>
<li>若超过 30 分钟未支付,请重新发起充值申请。</li>
<li>资金安全由平台承保,请放心按照指引操作。</li>
<li>如有任何疑问,请点击右侧客服对话框进行咨询。</li>
</ul>
</div>
</div>
</div>
<!-- Upload Form with Strict Enforcement -->
<form method="POST" enctype="multipart/form-data" id="proof-form">
<div style="background: #0b0e11; padding: 30px; border-radius: 20px; border: 2px dashed #2b3139; text-align: center; cursor: pointer; transition: 0.3s;" id="upload-zone" onclick="document.getElementById('proof-file').click()">
<div id="upload-idle">
<i class="fas fa-cloud-upload-alt" style="font-size: 50px; color: #5e6673; margin-bottom: 15px;"></i>
<div style="font-weight: bold; margin-bottom: 5px;">上传支付凭证 / Upload Voucher</div>
<div style="color: #5e6673; font-size: 12px;">点击或拖拽转账成功回单截图到此处</div>
<div style="color: #f0b90b; font-size: 11px; margin-top: 10px;">* 强制要求:必须上传凭证后才可点击确认完成</div>
</div>
<div id="upload-preview" style="display: none;">
<i class="fas fa-file-image" style="font-size: 50px; color: #00c087; margin-bottom: 15px;"></i>
<div style="font-weight: bold; color: #00c087;">文件已就绪 / File Ready</div>
<div id="filename-display" style="font-size: 12px; color: #848e9c; margin-top: 5px;"></div>
<div style="color: #var(--primary-color); font-size: 11px; margin-top: 10px;">点击此处可更换文件</div>
</div>
<input type="file" name="proof" id="proof-file" accept="image/*" style="display: none;" onchange="handleFileSelect(this)">
</div>
<button type="submit" id="submit-btn" disabled class="btn-primary" style="width: 100%; padding: 20px; font-size: 1.2rem; border-radius: 16px; margin-top: 25px; opacity: 0.5; cursor: not-allowed; transition: 0.3s; font-weight: 800;">
确认转账完成 / Transfer Completed
</button>
</form>
</div>
<?php else: ?>
<!-- Phase 3: Review State -->
<div style="text-align: center; padding: 80px 0;">
<div style="width: 100px; height: 100px; background: rgba(240, 185, 11, 0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 30px;">
<i class="fas fa-hourglass-half" style="font-size: 40px; color: #f0b90b; animation: pulse 2s infinite;"></i>
</div>
<h2 style="font-size: 2rem; margin-bottom: 20px;">充值审核中 / Under Review</h2>
<p style="color: #848e9c; line-height: 2; max-width: 600px; margin: 0 auto 40px; font-size: 1.1rem;">
您的支付凭证已成功提交。系统后台人员正在核实资金到账情况,预计将在 <b style="color: #fff;">15-30分钟</b> 内为您更新余额。
您可以随时在右侧与客服沟通进度。
</p>
<div style="display: flex; gap: 20px; justify-content: center;">
<a href="profile.php" style="background: var(--primary-color); color: white; padding: 15px 40px; border-radius: 12px; text-decoration: none; font-weight: bold; transition: 0.3s;">查看资产 / View Assets</a>
<a href="deposit.php" style="background: #2b3139; color: white; padding: 15px 40px; border-radius: 12px; text-decoration: none; font-weight: bold; transition: 0.3s;">再次充值 / Deposit Again</a>
</div>
</div>
<?php endif; ?>
</div>
<!-- Right Side: Chat Interface (CS) -->
<div style="background: #161a1e; border-radius: 24px; border: 1px solid #2b3139; display: flex; flex-direction: column; height: 750px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
<div style="padding: 25px; border-bottom: 1px solid #2b3139; background: #1e2329; display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center; gap: 15px;">
<div style="position: relative;">
<div style="width: 45px; height: 45px; background: linear-gradient(135deg, var(--primary-color), #4facfe); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px;">
<i class="fas fa-headset" style="color: white;"></i>
</div>
<div style="position: absolute; bottom: 0; right: 0; width: 12px; height: 12px; background: #00c087; border: 2px solid #1e2329; border-radius: 50%;"></div>
</div>
<div>
<div style="font-weight: 800; font-size: 15px; color: white;">NovaEx 官方客服</div>
<div style="font-size: 11px; color: #00c087;">专席已接入 · 实时响应中</div>
</div>
</div>
</div>
<div id="chat-box" style="flex: 1; overflow-y: auto; padding: 25px; display: flex; flex-direction: column; gap: 20px; background: #0b0e11; scroll-behavior: smooth;">
<div style="text-align: center; margin-bottom: 10px;">
<span style="background: rgba(255,255,255,0.05); padding: 4px 12px; border-radius: 20px; font-size: 10px; color: #5e6673;">已通过安全加密连接</span>
</div>
<div style="display: flex; flex-direction: column; align-items: flex-start;">
<div style="max-width: 85%; padding: 12px 16px; border-radius: 16px; font-size: 13px; line-height: 1.6; background: #2b3139; color: #EAECEF; border-bottom-left-radius: 2px;">
您好!我是您的专属充值助理。正在为您匹配最佳充值通道,请稍后。如有任何操作疑问请直接在此留言。
</div>
</div>
<?php foreach ($messages as $m): ?>
<div style="display: flex; flex-direction: column; align-items: <?php echo $m['sender'] === 'user' ? 'flex-end' : 'flex-start'; ?>;">
<div style="max-width: 85%; padding: 12px 16px; border-radius: 16px; font-size: 13px; line-height: 1.6;
<?php echo $m['sender'] === 'user' ? 'background: var(--primary-color); color: white; border-bottom-right-radius: 2px;' : 'background: #2b3139; color: #EAECEF; border-bottom-left-radius: 2px;'; ?>">
<?php echo nl2br(htmlspecialchars($m['message'])); ?>
</div>
<span style="font-size: 9px; color: #555; margin-top: 6px;"><?php echo date('H:i', strtotime($m['created_at'])); ?></span>
</div>
<?php endforeach; ?>
</div>
<div style="padding: 25px; border-top: 1px solid #2b3139; background: #1e2329;">
<form id="chat-form" style="display: flex; gap: 12px;">
<input type="text" id="chat-input" placeholder="请描述您的问题..." style="flex: 1; background: #0b0e11; border: 1px solid #2b3139; border-radius: 12px; padding: 14px 18px; color: white; outline: none; font-size: 14px; transition: 0.3s;">
<button type="submit" style="width: 50px; height: 50px; border-radius: 12px; background: var(--primary-color); border: none; color: white; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: 0.3s;">
<i class="fas fa-paper-plane"></i>
</button>
</form>
</div>
</div>
</div>
</main>
<style>
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
@keyframes pulse { 0% { opacity: 0.6; } 50% { opacity: 1; } 100% { opacity: 0.6; } }
.loader-ring { box-shadow: 0 0 20px rgba(79, 172, 254, 0.2); }
#chat-input:focus { border-color: var(--primary-color); box-shadow: 0 0 10px rgba(0, 82, 255, 0.1); }
#upload-zone:hover { border-color: var(--primary-color); background: rgba(0, 82, 255, 0.02); }
</style>
<script>
// Countdown Timer
let expiresAt = new Date('<?php echo $order['expires_at']; ?>').getTime();
function updateCountdown() {
let now = new Date().getTime();
let diff = expiresAt - now;
let elements = document.querySelectorAll('#countdown');
if (diff <= 0) {
elements.forEach(el => el.innerText = "00:00");
return;
}
let mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
let secs = Math.floor((diff % (1000 * 60)) / 1000);
let timeStr = (mins < 10 ? "0" + mins : mins) + ":" + (secs < 10 ? "0" + secs : secs);
elements.forEach(el => el.innerText = timeStr);
}
if (document.querySelectorAll('#countdown').length > 0) {
updateCountdown();
setInterval(updateCountdown, 1000);
}
// Auto refresh for order status (to show bank details when admin provides them)
<?php if ($order['status'] === 'matching' && !$order['bank_account_info']): ?>
setInterval(() => {
fetch('api/check_order_status.php?order_id=<?php echo $order_id; ?>')
.then(r => r.json())
.then(data => {
if (data.bank_account_info) {
location.href = location.href; // Refresh to show matched state
}
});
}, 4000);
<?php endif; ?>
// Handle File Selection and UI Toggle
function handleFileSelect(input) {
const btn = document.getElementById('submit-btn');
const idle = document.getElementById('upload-idle');
const preview = document.getElementById('upload-preview');
const filename = document.getElementById('filename-display');
if (input.files && input.files[0]) {
btn.disabled = false;
btn.style.opacity = "1";
btn.style.cursor = "pointer";
btn.style.background = "#00c087";
idle.style.display = "none";
preview.style.display = "block";
filename.innerText = input.files[0].name;
document.getElementById('upload-zone').style.borderColor = "#00c087";
document.getElementById('upload-zone').style.background = "rgba(0, 192, 135, 0.05)";
}
}
// Chat functionality
const chatBox = document.getElementById('chat-box');
chatBox.scrollTop = chatBox.scrollHeight;
document.getElementById('chat-form').onsubmit = function(e) {
e.preventDefault();
const input = document.getElementById('chat-input');
const msg = input.value.trim();
if (!msg) return;
const originalBtnHtml = this.querySelector('button').innerHTML;
this.querySelector('button').innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
fetch('chat.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'message=' + encodeURIComponent(msg)
}).then(() => {
input.value = '';
location.reload();
});
};
// Auto refresh chat
let messageCount = <?php echo count($messages); ?>;
setInterval(() => {
fetch('api/get_messages.php')
.then(r => r.json())
.then(data => {
if (data.count > messageCount) {
location.reload();
}
});
}, 5000);
</script>
<?php include 'footer.php'; ?>