diff --git a/about.php b/about.php index 3fc691c..bba6b9d 100644 --- a/about.php +++ b/about.php @@ -6,28 +6,28 @@ require_once __DIR__ . '/includes/header.php';

-
-

-

-

+

+

+

+

-

-

+

+

5M+

-

+

100+

-

+

$10B+

-

+

diff --git a/admin/customer_service.php b/admin/customer_service.php index f21ee1a..c943656 100644 --- a/admin/customer_service.php +++ b/admin/customer_service.php @@ -250,86 +250,83 @@ let currentUserContext = ''; async function refreshUsers() { try { + const searchInput = document.getElementById('user-search'); + const search = searchInput ? searchInput.value.toLowerCase() : ''; + const r = await fetch('/api/chat.php?action=admin_get_all'); const users = await r.json(); + const list = document.getElementById('user-list'); + if (!list) return; + if (users.error) { - console.error('API Error:', users.error); + list.innerHTML = `
接口错误: ${users.error}
`; return; } if (!Array.isArray(users)) { - console.error('API response is not an array:', users); + list.innerHTML = `
数据格式错误
`; + return; + } + + if (users.length === 0) { + list.innerHTML = '
暂无活跃会话 (720h内)
'; return; } - const list = document.getElementById('user-list'); - const searchInput = document.getElementById('user-search'); - const search = searchInput ? searchInput.value.toLowerCase() : ''; - let html = ''; users.forEach(u => { - try { - const userId = u.user_id; - const username = u.username || '匿名用户'; - const uid = u.uid || '---'; - const ip = u.ip_address || '---'; - const rawRemark = u.remark || ''; - const remark = rawRemark.toString().replace(/\n/g, " "); - const userTime = u.user_time || '---'; - const lastTime = u.created_at ? new Date(u.created_at.replace(/-/g, "/")) : new Date(); - - let lastMsgText = u.message || ''; - if (lastMsgText.startsWith('[PAYMENT_INFO]')) { - lastMsgText = '[收款账号信息]'; - } - - const isActive = (selectedIp === ip && selectedUser == userId); - if (isActive) { - const infoUserTime = document.getElementById('info-user-time'); - if (infoUserTime) infoUserTime.innerText = userTime; - } - - // Using data attributes to avoid escaping issues in onclick - html += ` -
-
- ${username} - ${lastTime.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit'})} -
- ${rawRemark ? `
[备注: ${rawRemark}]
` : ''} -
${lastMsgText}
-
- UID: ${uid} - ${ip} -
-
- `; - } catch (e) { - console.error('Error rendering user card:', e, u); + const userId = u.user_id || 0; + const username = (u.username || '匿名用户').toString(); + const uid = (u.uid || '---').toString(); + const ip = (u.ip_address || '---').toString(); + const rawRemark = (u.remark || '').toString(); + const userTime = (u.user_time || '---').toString(); + const lastTimeStr = u.created_at ? u.created_at.replace(/-/g, "/") : new Date().toISOString(); + const lastTime = new Date(lastTimeStr); + + // Search filter + if (search && !username.toLowerCase().includes(search) && !ip.includes(search) && !uid.includes(search)) { + return; } + + let lastMsgText = (u.message || '').toString(); + if (lastMsgText.startsWith('[PAYMENT_INFO]')) { + lastMsgText = '[收款账号信息]'; + } + + const isActive = (selectedIp === ip && selectedUser == userId); + + // Safe strings for onclick + const jsName = username.replace(/\\/g, '\\\\').replace(/'/g, "\\'"); + const jsRemark = rawRemark.replace(/\\/g, '\\\\').replace(/'/g, "\\'"); + + html += ` +
+
+ ${username} + ${isNaN(lastTime.getTime()) ? '---' : lastTime.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit'})} +
+ ${rawRemark ? `
[备注: ${rawRemark}]
` : ''} +
${lastMsgText}
+
+ UID: ${uid} + ${ip} +
+
+ `; }); - list.innerHTML = html || '
暂无活跃会话
'; + list.innerHTML = html || '
未找到匹配的会话
'; } catch (err) { console.error('Refresh users failed:', err); + const list = document.getElementById('user-list'); + if (list) { + list.innerHTML = `
脚本运行错误,请刷新页面
`; + } } } -// Handle clicks on user cards using event delegation -document.getElementById('user-list').addEventListener('click', (e) => { - const card = e.target.closest('.user-card'); - if (card) { - const d = card.dataset; - openChat(d.userId, d.ip, d.name, d.uid, d.remark, d.userTime); - } -}); - function openChat(userId, ip, name, uid, remark, userTime) { selectedUser = userId; selectedIp = ip; @@ -347,7 +344,7 @@ function openChat(userId, ip, name, uid, remark, userTime) { lastMsgId = 0; fetchMessages(); - refreshUsers(); // Refresh list to update active state + refreshUsers(); } async function recallMessage(msgId) { @@ -391,7 +388,6 @@ async function fetchMessages() { const msgs = await r.json(); if (!msgs || !Array.isArray(msgs)) return; - // If user changed, clear everything const context = selectedUser + '_' + selectedIp; if (currentUserContext !== context) { document.getElementById('messages-area').innerHTML = ''; @@ -427,7 +423,7 @@ async function fetchMessages() { function appendMessageHTML(m) { const area = document.getElementById('messages-area'); - if (!area || area.querySelector(`[data-id="${m.id}"]`)) return; + if (!area) return; const time = m.created_at || new Date().toISOString(); const msgDate = time.includes('-') ? new Date(time.replace(/-/g, "/")) : new Date(time); @@ -440,10 +436,10 @@ function appendMessageHTML(m) { div.className = `msg ${m.sender === 'admin' ? 'msg-admin' : 'msg-user'}`; div.setAttribute('data-id', m.id); - let displayMsg = m.message; + let displayMsg = (m.message || '').toString(); if (isPaymentInfo) { try { - const info = JSON.parse(m.message.replace('[PAYMENT_INFO]', '')); + const info = JSON.parse(displayMsg.replace('[PAYMENT_INFO]', '')); displayMsg = `
已发送收款账号
${info.bank} - ${info.name}
@@ -469,9 +465,10 @@ document.getElementById('plus-btn').addEventListener('click', () => { document.getElementById('image-input').click(); }); -const paymentModal = new bootstrap.Modal(document.getElementById('paymentModal')); +const paymentModalEl = document.getElementById('paymentModal'); +const paymentModal = paymentModalEl ? new bootstrap.Modal(paymentModalEl) : null; document.getElementById('payment-btn').addEventListener('click', () => { - paymentModal.show(); + if (paymentModal) paymentModal.show(); }); async function sendPaymentInfo() { @@ -497,8 +494,7 @@ async function sendPaymentInfo() { const r = await fetch('/api/chat.php?action=admin_send', { method: 'POST', body: fd }); const res = await r.json(); if (res.success) { - paymentModal.hide(); - // Clear inputs + if (paymentModal) paymentModal.hide(); document.getElementById('pay-bank').value = ''; document.getElementById('pay-name').value = ''; document.getElementById('pay-account').value = ''; @@ -512,7 +508,6 @@ document.getElementById('image-input').addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return; - // Local preview for "0 latency" const localUrl = URL.createObjectURL(file); const tempId = 'temp_img_' + Date.now(); const localMsgHtml = ``; @@ -524,7 +519,7 @@ document.getElementById('image-input').addEventListener('change', async (e) => { created_at: new Date().toISOString() }); const area = document.getElementById('messages-area'); - area.scrollTop = area.scrollHeight; + if (area) area.scrollTop = area.scrollHeight; const formData = new FormData(); formData.append('file', file); @@ -538,13 +533,12 @@ document.getElementById('image-input').addEventListener('change', async (e) => { }); const res = await r.json(); - // Remove temp const tempMsg = document.querySelector(`[data-id="${tempId}"]`); if (tempMsg) tempMsg.remove(); if (res.success && res.message) { appendMessageHTML(res.message); - area.scrollTop = area.scrollHeight; + if (area) area.scrollTop = area.scrollHeight; fetchMessages(); } else { alert('上传失败: ' + res.error); @@ -554,7 +548,7 @@ document.getElementById('image-input').addEventListener('change', async (e) => { if (tempMsg) tempMsg.remove(); } - e.target.value = ''; // Reset + e.target.value = ''; setTimeout(() => URL.revokeObjectURL(localUrl), 5000); }); @@ -566,7 +560,6 @@ document.getElementById('chat-form').addEventListener('submit', async (e) => { input.value = ''; - // Optimistic UI const tempId = 'temp_msg_' + Date.now(); appendMessageHTML({ id: tempId, @@ -575,7 +568,7 @@ document.getElementById('chat-form').addEventListener('submit', async (e) => { created_at: new Date().toISOString() }); const area = document.getElementById('messages-area'); - area.scrollTop = area.scrollHeight; + if (area) area.scrollTop = area.scrollHeight; const fd = new URLSearchParams(); fd.append('message', msg); @@ -591,7 +584,7 @@ document.getElementById('chat-form').addEventListener('submit', async (e) => { if (res.success && res.message) { appendMessageHTML(res.message); - area.scrollTop = area.scrollHeight; + if (area) area.scrollTop = area.scrollHeight; fetchMessages(); } } catch(err) {} diff --git a/admin/finance.php b/admin/finance.php index 006692e..b8a81d7 100644 --- a/admin/finance.php +++ b/admin/finance.php @@ -95,7 +95,7 @@ ob_start(); $type = $_GET['type'] ?? 'recharge'; $user_id = isset($_GET['user_id']) ? (int)$_GET['user_id'] : null; -$sql = "SELECT r.*, u.username, u.uid FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = ?"; +$sql = "SELECT r.*, u.username, u.uid FROM finance_requests r LEFT JOIN users u ON r.user_id = u.id WHERE r.type = ?"; $params = [$type]; if ($admin['is_agent']) { @@ -155,8 +155,8 @@ $requests = $stmt->fetchAll(); -
- +
+ diff --git a/api.php b/api.php index a8e5dc1..a7ff5d0 100644 --- a/api.php +++ b/api.php @@ -4,48 +4,48 @@ require_once __DIR__ . '/includes/header.php'; ?>

-
+
-

-

+

+

-

-

-
+

+

+
Authorization: Bearer YOUR_API_KEY
-

-
-
- GET /api/v1/market/ticker?symbol=BTCUSDT +

+
+
+ GET /api/v1/market/ticker?symbol=BTCUSDT
-

+

-

-
-
+

+
+
POST /api/v1/trade/order
-

-
{
+                    

+
{
   "symbol": "BTCUSDT",
   "side": "buy",
   "type": "limit",
diff --git a/api/chat.php b/api/chat.php
index 1ec118e..5c80a07 100644
--- a/api/chat.php
+++ b/api/chat.php
@@ -135,6 +135,7 @@ if ($action === 'ping') {
 
 if ($action === 'admin_get_all') {
     header('Content-Type: application/json');
+    
     if (!isset($_SESSION['admin_id'])) {
         echo json_encode(['error' => 'Unauthorized']);
         exit;
@@ -147,18 +148,18 @@ if ($action === 'admin_get_all') {
                 v.ip_address, 
                 CASE 
                     WHEN m.message LIKE ' DATE_SUB(NOW(), INTERVAL 72 HOUR)
+            WHERE v.last_activity > DATE_SUB(NOW(), INTERVAL 720 HOUR)
             ORDER BY created_at DESC
         ");
         echo json_encode($stmt->fetchAll());
     } catch (Exception $e) {
+        error_log("Chat API Error: " . $e->getMessage());
         echo json_encode(['error' => $e->getMessage()]);
     }
     exit;
diff --git a/assets/pasted-20260221-025919-b4305aa6.png b/assets/pasted-20260221-025919-b4305aa6.png
new file mode 100644
index 0000000..29f755f
Binary files /dev/null and b/assets/pasted-20260221-025919-b4305aa6.png differ
diff --git a/fees.php b/fees.php
index c255a23..733c293 100644
--- a/fees.php
+++ b/fees.php
@@ -4,14 +4,14 @@ require_once __DIR__ . '/includes/header.php';
 ?>
 

-
-

+
+

-

+

- + @@ -19,25 +19,25 @@ require_once __DIR__ . '/includes/header.php'; - + - + - + - + @@ -47,23 +47,23 @@ require_once __DIR__ . '/includes/header.php';
0 () < $10,000 0.100% 0.100%
1 ≥ $10,000 0.080% 0.090%
2 ≥ $100,000 0.060% 0.080%
3 ≥ $500,000 0.040%
-

+

- + - + - + diff --git a/help.php b/help.php index 9c5ce9a..8776bb9 100644 --- a/help.php +++ b/help.php @@ -5,7 +5,7 @@ require_once __DIR__ . '/includes/header.php';

-

+

@@ -14,50 +14,50 @@ require_once __DIR__ . '/includes/header.php';
-
+
-

-

+

+

-
+
-

-

+

+

-
+
-

-

+

+

-
+
-

-

+

+

-
+
-

-

+

+

-
+
-

-

+

+

diff --git a/includes/footer.php b/includes/footer.php index 16352eb..e21fc16 100644 --- a/includes/footer.php +++ b/includes/footer.php @@ -330,11 +330,11 @@ csForm.addEventListener('submit', async (e) => { }); function appendMessageHTML(m) { - if (document.querySelector(`[data-id="${m.id}"]`)) return; + if (!m || !m.id || document.querySelector(`[data-id="${m.id}"]`)) return; const sender = m.sender; - const text = m.message; - const time = m.created_at; + const text = (m.message || '').toString(); + const time = m.created_at || new Date().toISOString(); const isImage = text.indexOf(' diff --git a/includes/lang.php b/includes/lang.php index 6f73adf..82c629f 100644 --- a/includes/lang.php +++ b/includes/lang.php @@ -551,6 +551,43 @@ $translations = [ 'step_4' => '转账完成后在聊天框告知客服或等待系统同步', 'recharge_success_title' => '申请已提交', 'recharge_success_text' => '您的充值申请已收到,请等待审核通过。', + 'recharge_instruction_1' => '系统正在为您分配专属收款账户,请耐心等待', + 'recharge_instruction_2' => '匹配期间请勿刷新页面或重复提交订单', + 'recharge_instruction_3' => '若超过倒计时仍未匹配成功,请及时联系在线客服', + 'recharge_instruction_4' => '收到充值账户,完成转账后,请将转账凭证提交给在线客服', + 'recharge_instruction_5' => '客服将在核实资金后为您确认到账', + 'finished_transfer' => '完成转账', + 'matching_instructions' => '匹配说明', + 'matching_system_active' => '匹配系统已激活', + 'high_encryption' => '高等级加密', + 'online' => '在线', + 'ip' => 'IP:', + 'news_title_1' => 'BYRO正式上线全新秒合约交易系统', + 'news_title_2' => '关于新增多种支付方式的公告', + 'news_title_3' => 'BYRO获得数字货币运营牌照', + 'news_title_4' => '提升账户安全:启用谷歌身份验证器', + 'news_title_5' => '2026年市场研究报告:加密货币的未来', + 'news_desc_1' => '我们很高兴地宣布,BYRO全新的秒合约系统已正式上线,提供更快的结算速度。', + 'news_desc_2' => '为了方便全球用户,我们新增了包括本地银行转账在内的多种法币充值方式。', + 'news_desc_3' => 'BYRO致力于合规化运营,近期已成功获得关键市场的运营许可。', + 'news_desc_4' => '用户的资产安全是我们的首要任务,我们建议所有用户开启谷歌二次验证。', + 'news_desc_5' => '深入了解2026年加密货币市场的发展趋势和潜在机会。', + 'news_meta' => '发布于 2026年2月21日 • 公告', + 'help_subtitle' => '在这里您可以找到有关使用BYRO的所有问题的答案', + 'help_search_placeholder' => '搜索问题、功能或教程...', + 'getting_started' => '新手入门', + 'getting_started_desc' => '了解如何注册账户并开始您的第一笔交易。', + 'dep_with_title' => '充值与提现', + 'dep_with_desc' => '关于如何存入资金和提取资产的详细指南。', + 'trading_tutorials' => '交易教程', + 'trading_tutorials_desc' => '掌握现货、合约和秒合约的交易技巧。', + 'sec_acc_title' => '账户安全', + 'sec_acc_desc' => '保护您的账户免受未经授权的访问。', + 'api_doc_title' => '接口文档', + 'api_doc_desc' => '为开发者提供的完整 API 集成文档。', + 'contact_sup_title' => '联系支持', + 'contact_sup_desc' => '如果您遇到问题,我们的团队将全天候为您服务。', + 'fees_content' => 'BYRO采用透明的费率结构,旨在为用户提供最具竞争力的交易成本。', ], 'en' => [ 'home' => 'Home', @@ -1081,6 +1118,43 @@ $translations = [ 'step_4' => 'Click "I have paid" in chat or wait for system sync', 'recharge_success_title' => 'Request Submitted', 'recharge_success_text' => 'Your recharge request has been received. Please wait for approval.', + 'recharge_instruction_1' => 'System is allocating an exclusive account for you, please wait patiently.', + 'recharge_instruction_2' => 'Do not refresh the page or resubmit the order during matching.', + 'recharge_instruction_3' => 'If matching fails after the countdown, please contact support.', + 'recharge_instruction_4' => 'After receiving the account, submit the transfer voucher to support.', + 'recharge_instruction_5' => 'Support will confirm your deposit after verifying the funds.', + 'finished_transfer' => 'Finished Transfer', + 'matching_instructions' => 'Matching Instructions', + 'matching_system_active' => 'MATCHING SYSTEM ACTIVE', + 'high_encryption' => 'HIGH ENCRYPTION', + 'online' => 'ONLINE', + 'ip' => 'IP:', + 'news_title_1' => 'BYRO Officially Launches New Binary Trading System', + 'news_title_2' => 'Announcement on New Payment Methods', + 'news_title_3' => 'BYRO Obtains Digital Currency Operation License', + 'news_title_4' => 'Enhance Account Security: Enable Google Authenticator', + 'news_title_5' => '2026 Market Research: The Future of Crypto', + 'news_desc_1' => 'We are excited to announce that BYRO\'s new binary system is live, offering faster settlement.', + 'news_desc_2' => 'To facilitate global users, we have added multiple fiat deposit methods including local bank transfers.', + 'news_desc_3' => 'BYRO is committed to compliant operations and has successfully obtained key licenses.', + 'news_desc_4' => 'Your security is our priority. We recommend all users enable Google 2FA.', + 'news_desc_5' => 'Deep dive into the 2026 crypto market trends and potential opportunities.', + 'news_meta' => 'Published on Feb 21, 2026 • Announcement', + 'help_subtitle' => 'Find answers to all your questions about using BYRO', + 'help_search_placeholder' => 'Search for issues, features or tutorials...', + 'getting_started' => 'Getting Started', + 'getting_started_desc' => 'Learn how to register and start your first trade.', + 'dep_with_title' => 'Deposit & Withdraw', + 'dep_with_desc' => 'Detailed guides on how to fund and withdraw from your account.', + 'trading_tutorials' => 'Trading Tutorials', + 'trading_tutorials_desc' => 'Master spot, contract, and binary trading skills.', + 'sec_acc_title' => 'Account Security', + 'sec_acc_desc' => 'Protect your account from unauthorized access.', + 'api_doc_title' => 'API Documentation', + 'api_doc_desc' => 'Complete API integration documentation for developers.', + 'contact_sup_title' => 'Contact Support', + 'contact_sup_desc' => 'Our team is available 24/7 if you encounter any issues.', + 'fees_content' => 'BYRO uses a transparent fee structure designed to provide competitive trading costs.', ], ]; diff --git a/legal.php b/legal.php index 488a85a..6fd27a7 100644 --- a/legal.php +++ b/legal.php @@ -6,27 +6,27 @@ require_once __DIR__ . '/includes/header.php';

-
-

+
+

-

-

+

+

-

-

+

+

-

-

+

+

-

-

+

+

-

-

+

+

diff --git a/news.php b/news.php index ac78b23..f2c8e3c 100644 --- a/news.php +++ b/news.php @@ -6,29 +6,29 @@ require_once __DIR__ . '/includes/header.php';

-

+

-
+
-

-

-

- +

+

+

+
-
-
-

+
+
+


-
+
#BTC #Web3 diff --git a/recharge.php b/recharge.php index 31813d7..565c51a 100644 --- a/recharge.php +++ b/recharge.php @@ -1,12 +1,23 @@ prepare("SELECT * FROM users WHERE id = ?"); + $stmt->execute([$_SESSION['user_id']]); + $user = $stmt->fetch(); +} if (!$user) { header('Location: /auth/login.php'); exit; } +require_once __DIR__ . '/includes/header.php'; +require_once __DIR__ . '/includes/exchange.php'; + // Fetch rates $rates = get_exchange_rates(); @@ -209,8 +220,8 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
- ONLINE - IP: + +
@@ -241,49 +252,69 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
-
+
-
+
-
- +
+
-

...

-

+

+

-
-
-
-
- +
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
- +
+
+
-
-
系统正在为您分配专属收款账户,请耐心等待
-
匹配期间请勿刷新页面或重复提交订单
-
若超过倒计时仍未匹配成功,请及时联系在线客服
-
收到充值账户,完成转账后,请将转账凭证提交给在线客服
-
客服将在核实资金后为您确认到账
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
@@ -375,10 +406,58 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc box-shadow: 0 4px 15px rgba(0,0,0,0.2); } @media (max-width: 992px) { - .chat-column { height: 450px !important; } - .modal-xl { margin: 10px; max-width: calc(100% - 20px); } - .modal-dialog-centered { align-items: flex-start; } - .info-side { padding: 1.5rem !important; } + .chat-column { display: none !important; } + .info-side { + width: 100% !important; + min-height: 100vh !important; + border-radius: 24px !important; + } + .modal-dialog { margin: 0; } + .modal-content { border-radius: 0; height: 100vh; } +} + +/* Premium Desktop Styling */ +.modal-content { + box-shadow: 0 0 50px rgba(0,0,0,0.5), 0 0 100px rgba(0,123,255,0.1) !important; +} +.info-side { + background: #1c2127; + border-radius: 0 24px 24px 0; +} +@media (max-width: 992px) { + .info-side { border-radius: 24px; } +} +.text-shadow-ultra { + text-shadow: 0 4px 15px rgba(0,0,0,0.6), 0 0 40px rgba(0,123,255,0.4); + letter-spacing: 1px; + font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif; +} +.tracking-wider { + letter-spacing: 0.15em; +} +.vibrancy-bg { + background: linear-gradient(135deg, #0f172a 0%, #1e3a8a 30%, #1e40af 60%, #1d4ed8 100%); + opacity: 0.85; +} +.instruction-item { + background: rgba(255,255,255,0.04); + border: 1px solid rgba(255,255,255,0.08); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + backdrop-filter: blur(5px); +} +.instruction-item:hover { + background: rgba(255,255,255,0.08); + transform: translateX(8px); + border-color: rgba(255,255,255,0.15); +} +.display-5 { + font-size: 3.5rem; + font-weight: 800; +} +@media (min-width: 992px) { + .modal-xl { + max-width: 1000px; + } } @@ -438,40 +517,104 @@ function selectNetwork(net, addr) { const userId = ''; let rechargeCountdownInterval; let modalChatLastIds = new Set(); +let remainingSeconds = 1800; -function openRechargeModal(initialMessage) { - const modal = new bootstrap.Modal(document.getElementById('rechargeModal')); +function saveRechargeState(state) { + localStorage.setItem('recharge_state', JSON.stringify({ + ...state, + timestamp: Date.now(), + remainingSeconds: remainingSeconds + })); +} + +function clearRechargeState() { + localStorage.removeItem('recharge_state'); + if (rechargeCountdownInterval) clearInterval(rechargeCountdownInterval); +} + +function finishTransfer() { + clearRechargeState(); + bootstrap.Modal.getInstance(document.getElementById('rechargeModal'))?.hide(); + notify('success', '', ''); +} + +function openRechargeModal(initialMessage, isRestore = false) { + const modalElement = document.getElementById('rechargeModal'); + const modal = new bootstrap.Modal(modalElement); modal.show(); + if (!isRestore) { + remainingSeconds = 1800; + saveRechargeState({ phase: 'matching', initialMessage }); + } + // Start countdown - let seconds = 1800; const display = document.getElementById('modal-countdown'); if (rechargeCountdownInterval) clearInterval(rechargeCountdownInterval); rechargeCountdownInterval = setInterval(() => { - let mins = Math.floor(seconds / 60); - let secs = seconds % 60; - display.innerText = `${mins}:${secs < 10 ? '0' : ''}${secs}`; - if (--seconds < 0) clearInterval(rechargeCountdownInterval); + let mins = Math.floor(remainingSeconds / 60); + let secs = remainingSeconds % 60; + if (display) display.innerText = `${mins}:${secs < 10 ? '0' : ''}${secs}`; + + const state = JSON.parse(localStorage.getItem('recharge_state') || '{}'); + state.remainingSeconds = remainingSeconds; + localStorage.setItem('recharge_state', JSON.stringify(state)); + + if (--remainingSeconds < 0) { + clearInterval(rechargeCountdownInterval); + } }, 1000); - // Send initial message and show in chat - const tempId = 'modal_temp_' + Date.now(); - appendModalMessage({ - id: tempId, - sender: 'user', - message: initialMessage, - created_at: new Date().toISOString() - }); - - // Ping first to register visitor, then send message - fetch(`/api/chat.php?action=ping&user_time=${encodeURIComponent(new Date().toLocaleString())}`) - .then(() => sendModalMessage(initialMessage)) - .catch(err => console.error('Ping failed:', err)); + // Clear chat last ids for new session if not restoring + if (!isRestore) { + modalChatLastIds.clear(); + document.getElementById('modal-chat-messages').innerHTML = ` +
+ +
+ `; + + // Ping first to register visitor, then send message to ensure visibility + const userTime = new Date().toLocaleString('zh-CN'); + fetch(`/api/chat.php?action=ping&user_time=${encodeURIComponent(userTime)}`) + .then(() => { + // Append locally first + appendModalMessage({ + id: 'modal_temp_init_' + Date.now(), + sender: 'user', + message: initialMessage, + created_at: new Date().toISOString() + }); + // Then send to server + return sendModalMessage(initialMessage); + }) + .catch(err => console.error('Initial sequence failed:', err)); + } // Start polling for modal initModalChat(); } +document.addEventListener('DOMContentLoaded', () => { + const savedState = localStorage.getItem('recharge_state'); + if (savedState) { + const state = JSON.parse(savedState); + const elapsed = Math.floor((Date.now() - state.timestamp) / 1000); + remainingSeconds = (state.remainingSeconds || 1800) - elapsed; + + if (remainingSeconds > 0) { + if (state.phase === 'matched') { + openRechargeModal(state.initialMessage, true); + updateMatchingSide(state.info, true); + } else { + openRechargeModal(state.initialMessage, true); + } + } else { + localStorage.removeItem('recharge_state'); + } + } +}); + let modalChatPolling = false; function initModalChat() { @@ -627,11 +770,16 @@ function appendModalMessage(m) { modalChatLastIds.add(m.id); } -function updateMatchingSide(info) { +function updateMatchingSide(info, isRestore = false) { const side = document.querySelector('.info-side'); if (!side) return; if (rechargeCountdownInterval) clearInterval(rechargeCountdownInterval); + + if (!isRestore) { + const state = JSON.parse(localStorage.getItem('recharge_state') || '{}'); + saveRechargeState({ ...state, phase: 'matched', info }); + } side.innerHTML = `
@@ -683,16 +831,19 @@ function updateMatchingSide(info) {
-
+
01
-
完成转账后,请将转账凭证提交给在线客服
+
02
-
客服将在核实资金后为您确认到账
+
+
`; diff --git a/support.php b/support.php index 545f64e..ade4c82 100644 --- a/support.php +++ b/support.php @@ -6,15 +6,15 @@ require_once __DIR__ . '/includes/header.php';

-
+
- - + +
- - @@ -23,16 +23,16 @@ require_once __DIR__ . '/includes/header.php';
- - + +
- +
- + -
+
diff --git a/tos.php b/tos.php index 01c5950..ff1d887 100644 --- a/tos.php +++ b/tos.php @@ -6,27 +6,27 @@ require_once __DIR__ . '/includes/header.php';

-
-

+
+

-

-

+

+

-

-

+

+

-

-

+

+

-

-

+

+

-

-

+

+

0.020% 0.050%
1 0.015% 0.045%