38350-vm/matching.php
2026-02-11 13:35:33 +00:00

347 lines
22 KiB
PHP

<?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';
$expires_at = date('Y-m-d H:i:s', strtotime('+30 minutes'));
$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();
$msg = "[RECHARGE_NOTIFICATION] 用户 {$_SESSION['email']} (UID: {$_SESSION['uid']}) 正在发起充值匹配: $amount $currency。订单号: #$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;
}
$order_id = $_GET['order_id'] ?? null;
if (!$order_id) {
header("Location: deposit.php");
exit;
}
$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;
}
if ($order['status'] === 'completed') {
header("Location: profile.php");
exit;
}
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]);
$msg = "[RECHARGE_SUBMITTED] 用户已上传支付凭证并确认转账 (订单 #$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;
}
}
$stmt = db()->prepare("SELECT * FROM messages WHERE user_id = ? AND message NOT LIKE '[RECHARGE_%' ORDER BY created_at ASC");
$stmt->execute([$user_id]);
$messages = $stmt->fetchAll();
?>
<main style="background: #0b0e11; min-height: calc(100vh - 64px); padding: 20px;">
<div style="max-width: 1200px; margin: 0 auto; background: #161a1e; border: 1px solid #2b3139; border-radius: 24px; height: 85vh; display: grid; grid-template-columns: 1fr 380px; overflow: hidden; box-shadow: 0 20px 50px rgba(0,0,0,0.5);">
<!-- Main Panel: Deposit Matching Workflow (The "Enlarged Dialog") -->
<div style="display: flex; flex-direction: column; border-right: 1px solid #2b3139; background: #0b0e11;">
<div style="padding: 20px 30px; border-bottom: 1px solid #2b3139; background: #161a1e; display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center; gap: 15px;">
<div style="width: 45px; height: 45px; background: var(--primary-color); border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 20px; color: white;">
<i class="fas fa-wallet"></i>
</div>
<div>
<div style="font-weight: 800; font-size: 16px;">充值订单匹配 / Recharge Matching</div>
<div style="font-size: 11px; color: #848e9c;">订单号: #<?php echo $order_id; ?></div>
</div>
</div>
<div style="text-align: right;">
<div id="countdown" style="font-size: 1.5rem; font-weight: 900; color: #f0b90b; font-family: 'Roboto Mono', monospace;">30:00</div>
<div style="font-size: 10px; color: #848e9c;">剩余有效时间 / Time Left</div>
</div>
</div>
<div style="flex: 1; overflow-y: auto; padding: 40px;">
<?php if ($order['status'] === 'matching' && !$order['bank_account_info']): ?>
<div style="text-align: center; max-width: 600px; margin: 40px auto;">
<div class="matching-loader" style="margin-bottom: 30px;">
<div class="ring"></div>
<div class="ring"></div>
<div class="ring"></div>
<i class="fas fa-search-dollar" style="font-size: 40px; color: var(--primary-color);"></i>
</div>
<h2 style="font-size: 2rem; margin-bottom: 10px; color: white;">正在为您匹配充值账户...</h2>
<p style="color: #848e9c; margin-bottom: 40px;">匹配过程中请勿关闭此页面,平均匹配时间 1-3 分钟。</p>
<div style="background: #161a1e; border-radius: 20px; padding: 30px; border: 1px solid #2b3139; text-align: left;">
<h4 style="margin-top: 0; margin-bottom: 20px; color: #f0b90b;"><i class="fas fa-exclamation-triangle"></i> 转账说明 & 安全提示</h4>
<div style="font-size: 14px; color: #EAECEF; line-height: 2;">
<p>• 系统正在随机为您匹配承兑商账户,请稍等片刻。</p>
<p>• 匹配成功后将显示收款银行卡、姓名及账号等详细信息。</p>
<p>• 请务必使用<b>本人姓名</b>对应的账户进行转账,否则无法入账。</p>
<p>• 转账时<b>严禁备注</b>任何关于加密货币、USDT等字眼。</p>
</div>
</div>
</div>
<?php elseif ($order['bank_account_info'] && $order['status'] !== 'submitting' && $order['status'] !== 'completed'): ?>
<div style="max-width: 700px; margin: 0 auto;">
<div style="background: #161a1e; border-radius: 24px; border: 1px solid #2b3139; overflow: hidden;">
<div style="background: rgba(0, 192, 135, 0.1); padding: 20px; display: flex; align-items: center; gap: 15px; border-bottom: 1px solid #2b3139;">
<i class="fas fa-check-circle" style="color: #00c087; font-size: 24px;"></i>
<div style="font-weight: bold; color: #00c087;">账户匹配成功,请在倒计时结束前完成转账</div>
</div>
<div style="padding: 30px;">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px;">
<div style="background: #0b0e11; padding: 15px; border-radius: 12px; border: 1px solid #2b3139;">
<div style="font-size: 11px; color: #848e9c; margin-bottom: 5px;">充值金额 / Amount</div>
<div style="font-size: 1.5rem; font-weight: 900; color: #f0b90b;"><?php echo number_format($order['amount'], 2); ?> <span style="font-size: 14px;"><?php echo $order['currency']; ?></span></div>
</div>
<div style="background: #0b0e11; padding: 15px; border-radius: 12px; border: 1px solid #2b3139;">
<div style="font-size: 11px; color: #848e9c; margin-bottom: 5px;">收款方式 / Method</div>
<div style="font-size: 1.1rem; font-weight: bold;">银行卡转账</div>
</div>
</div>
<div style="background: #0b0e11; padding: 25px; border-radius: 16px; border: 2px solid #2b3139; margin-bottom: 30px; position: relative;">
<div style="font-size: 12px; color: var(--primary-color); font-weight: bold; margin-bottom: 15px;">收款账户信息 / RECEIVING ACCOUNT</div>
<div style="font-size: 1.2rem; line-height: 2; color: white; font-family: 'Roboto Mono', monospace;">
<?php echo nl2br(htmlspecialchars($order['bank_account_info'])); ?>
</div>
<button onclick="copyToClipboard('<?php echo str_replace(["\r", "\n"], ' ', $order['bank_account_info']); ?>')" style="position: absolute; top: 20px; right: 20px; background: #2b3139; border: none; color: white; padding: 5px 10px; border-radius: 6px; font-size: 12px; cursor: pointer;">
<i class="fas fa-copy"></i> 复制
</button>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-bottom: 30px;">
<div style="font-size: 13px; color: #848e9c; line-height: 1.8;">
<h5 style="color: white; margin-bottom: 10px;">安全提示:</h5>
• 请勿在此聊天框外进行任何转账。<br>
• 官方客服不会向您索要密码。<br>
• 请确认收款人姓名后再汇款。
</div>
<div style="font-size: 13px; color: #848e9c; line-height: 1.8;">
<h5 style="color: white; margin-bottom: 10px;">转账说明:</h5>
• 转账完成后请务必保存截图。<br>
• 点击下方按钮上传凭证确认。<br>
• 资金通常在 15 分钟内到账。
</div>
</div>
<form method="POST" enctype="multipart/form-data" id="proof-form">
<div style="background: #0b0e11; padding: 25px; border-radius: 16px; 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: 30px; color: #5e6673; margin-bottom: 10px;"></i>
<div style="font-weight: bold; margin-bottom: 5px; font-size: 14px;">上传支付凭证 / Upload Voucher</div>
<div style="color: #f0b90b; font-size: 11px;">转账完成后点击此处上传凭证截图</div>
</div>
<div id="upload-preview" style="display: none;">
<i class="fas fa-file-image" style="font-size: 30px; color: #00c087; margin-bottom: 10px;"></i>
<div style="font-weight: bold; color: #00c087; font-size: 14px;">凭证已选择</div>
<div id="filename-display" style="font-size: 12px; color: #848e9c;"></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: 18px; font-size: 1.1rem; border-radius: 12px; margin-top: 20px; opacity: 0.5; cursor: not-allowed; font-weight: bold;">
完成转账 / Transfer Completed
</button>
</form>
</div>
</div>
</div>
<?php else: ?>
<div style="text-align: center; padding: 60px 0;">
<div style="width: 120px; height: 120px; 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-history" style="font-size: 50px; color: #f0b90b; animation: pulse-scale 2s infinite;"></i>
</div>
<h2 style="font-size: 2.2rem; margin-bottom: 20px; color: white;">充值完成请等待确认</h2>
<p style="color: #848e9c; line-height: 2; max-width: 500px; margin: 0 auto 40px; font-size: 15px;">
您的支付凭证已成功提交。客服人员正在核实资金到账情况,请稍候。核实完成后,本页面将自动跳转至您的资产页面。
</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;">查看我的资产</a>
<button onclick="location.reload()" style="background: transparent; border: 1px solid #2b3139; color: white; padding: 15px 40px; border-radius: 12px; font-weight: bold; cursor: pointer;">刷新状态</button>
</div>
</div>
<?php endif; ?>
</div>
</div>
<!-- Right Side: Chat Sidebar (The "Dialog" sidebar) -->
<div style="display: flex; flex-direction: column; background: #161a1e;">
<div style="padding: 20px; border-bottom: 1px solid #2b3139; background: #1e2329; display: flex; align-items: center; gap: 12px;">
<div style="position: relative;">
<div style="width: 45px; height: 45px; background: var(--primary-color); 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: 14px; color: white;">在线客服 (Support)</div>
<div style="font-size: 10px; color: #848e9c;">24/7 实时响应中</div>
</div>
</div>
<div id="chat-box" style="flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 15px; background: #0b0e11;">
<?php foreach ($messages as $m):
if (strpos($m['message'], '[SYSTEM]') === 0): ?>
<div style="align-self: center; font-size: 10px; color: #5e6673; background: rgba(255,255,255,0.05); padding: 5px 15px; border-radius: 20px;">
<?php echo htmlspecialchars(str_replace('[SYSTEM] ', '', $m['message'])); ?>
</div>
<?php else:
$align = $m['sender'] === 'user' ? 'flex-end' : 'flex-start';
$bgColor = $m['sender'] === 'user' ? 'var(--primary-color)' : '#2b3139';
$textColor = $m['sender'] === 'user' ? 'white' : '#EAECEF';
$borderRadius = $m['sender'] === 'user' ? 'border-bottom-right-radius: 2px;' : 'border-bottom-left-radius: 2px;';
?>
<div style="display: flex; flex-direction: column; align-items: <?php echo $align; ?>;">
<div style="max-width: 85%; padding: 10px 14px; border-radius: 14px; font-size: 13px; line-height: 1.5;
background: <?php echo $bgColor; ?>; color: <?php echo $textColor; ?>; <?php echo $borderRadius; ?>">
<?php echo nl2br(htmlspecialchars($m['message'])); ?>
</div>
<div style="font-size: 9px; color: #5e6673; margin-top: 4px;"><?php echo date('H:i', strtotime($m['created_at'])); ?></div>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
<div style="padding: 20px; background: #1e2329; border-top: 1px solid #2b3139;">
<form id="chat-form" style="display: flex; gap: 10px;">
<input type="text" id="chat-input" placeholder="输入您的问题..." style="flex: 1; background: #0b0e11; border: 1px solid #2b3139; border-radius: 12px; padding: 12px 15px; color: white; outline: none; font-size: 13px;">
<button type="submit" style="width: 45px; height: 45px; border-radius: 12px; background: var(--primary-color); border: none; color: white; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: 0.2s;">
<i class="fas fa-paper-plane"></i>
</button>
</form>
</div>
</div>
</div>
</main>
<style>
.matching-loader { position: relative; width: 100px; height: 100px; margin: 0 auto; display: flex; align-items: center; justify-content: center; }
.matching-loader .ring { position: absolute; width: 100%; height: 100%; border: 4px solid transparent; border-top: 4px solid var(--primary-color); border-radius: 50%; animation: spin 2s linear infinite; }
.matching-loader .ring:nth-child(2) { width: 80%; height: 80%; border-top: 4px solid #f0b90b; animation: spin-reverse 1.5s linear infinite; }
.matching-loader .ring:nth-child(3) { width: 60%; height: 60%; border-top: 4px solid #00c087; animation: spin 1s linear infinite; }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
@keyframes spin-reverse { 0% { transform: rotate(0deg); } 100% { transform: rotate(-360deg); } }
@keyframes pulse-scale { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.1); opacity: 0.8; } 100% { transform: scale(1); opacity: 1; } }
#upload-zone:hover { border-color: var(--primary-color); background: rgba(79, 172, 254, 0.05); }
.btn-primary:active { transform: scale(0.98); }
</style>
<script>
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"; el.style.color = "#ff4d4f"; }); 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); }
// Order status polling
setInterval(() => {
fetch('api/check_order_status.php?order_id=<?php echo $order_id; ?>')
.then(r => r.json())
.then(data => {
if (data.status === 'completed') { location.href = 'profile.php'; }
else if (data.bank_account_info && !document.getElementById('upload-zone') && '<?php echo $order['status']; ?>' === 'matching') { location.reload(); }
});
}, 4000);
function handleFileSelect(input) {
const btn = document.getElementById('submit-btn');
if (input.files && input.files[0]) {
btn.disabled = false; btn.style.opacity = "1"; btn.style.cursor = "pointer";
document.getElementById('upload-idle').style.display = "none";
document.getElementById('upload-preview').style.display = "block";
document.getElementById('filename-display').innerText = input.files[0].name;
}
}
function copyToClipboard(text) {
const el = document.createElement('textarea');
el.value = text;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
alert('已复制到剪贴板 / Copied to clipboard');
}
const chatBox = document.getElementById('chat-box');
if(chatBox) 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;
// Add message locally for instant feedback
const time = new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
const msgHtml = `<div style="display: flex; flex-direction: column; align-items: flex-end;">
<div style="max-width: 85%; padding: 10px 14px; border-radius: 14px; font-size: 13px; line-height: 1.5; background: var(--primary-color); color: white; border-bottom-right-radius: 2px;">${msg}</div>
<div style="font-size: 9px; color: #5e6673; margin-top: 4px;">${time}</div>
</div>`;
chatBox.insertAdjacentHTML('beforeend', msgHtml);
chatBox.scrollTop = chatBox.scrollHeight;
input.value = '';
fetch('chat.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'message=' + encodeURIComponent(msg) });
};
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'; ?>