diff --git a/about.php b/about.php index 0e2dd8c..3fc691c 100644 --- a/about.php +++ b/about.php @@ -8,28 +8,26 @@ require_once __DIR__ . '/includes/header.php';

-

Our Mission

+

- To make digital asset trading accessible, secure, and intuitive for everyone, everywhere. - We believe in the power of blockchain to transform the global financial landscape. +

-

Global Presence

+

- With offices in Singapore, London, and Tokyo, Byro serves a diverse global community. - We are compliant with international standards and prioritize the security of our users' assets. +

5M+

-

Users

+

100+

-

Countries

+

$10B+

-

Daily Volume

+

diff --git a/admin/customer_service.php b/admin/customer_service.php index 1603b6b..3d29561 100644 --- a/admin/customer_service.php +++ b/admin/customer_service.php @@ -138,7 +138,7 @@ async function fetchMessages() { filtered.forEach(m => { const div = document.createElement('div'); div.className = `msg ${m.sender === 'admin' ? 'msg-admin' : 'msg-user'}`; - div.innerText = m.message; + div.innerHTML = m.message; area.appendChild(div); }); area.scrollTop = area.scrollHeight; @@ -162,6 +162,13 @@ document.getElementById('chat-form').addEventListener('submit', async (e) => { fetchMessages(); }); +// Clear notifications when on this page +function clearNotifications() { + fetch('/api/admin_notifications.php?action=clear&type=messages'); +} +setInterval(clearNotifications, 5000); +clearNotifications(); + setInterval(refreshUsers, 3000); setInterval(fetchMessages, 1000); refreshUsers(); diff --git a/admin/layout.php b/admin/layout.php index f4fcab1..9c4ddf6 100644 --- a/admin/layout.php +++ b/admin/layout.php @@ -296,12 +296,28 @@ function renderAdminPage($content, $title = '后台管理') { } function checkNotifications() { + const currentPage = window.location.pathname; fetch('/api/admin_notifications.php') .then(r => r.json()) .then(data => { if (data.success) { const counts = data.counts; - const total = counts.total; + + // Auto-clear current page types + if (currentPage.includes('finance.php')) { + fetch('/api/admin_notifications.php?action=clear&type=finance'); + counts.recharge = 0; + counts.withdrawal = 0; + } else if (currentPage.includes('customer_service.php')) { + fetch('/api/admin_notifications.php?action=clear&type=messages'); + counts.messages = 0; + } else if (currentPage.includes('users.php')) { + fetch('/api/admin_notifications.php?action=clear&type=users'); + counts.users = 0; + } + // ... other pages can be added here + + const total = counts.recharge + counts.withdrawal + counts.kyc + counts.binary + counts.contract + counts.spot + counts.messages + counts.users; const soundTotal = counts.sound_total || 0; // Finance badge diff --git a/admin/settings.php b/admin/settings.php index 5820630..db44c5e 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -11,12 +11,34 @@ if (!isset($_SESSION['user_id'])) { $message = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $email_verify = isset($_POST['email_verification_enabled']) ? '1' : '0'; - $stmt = db()->prepare("UPDATE system_settings SET setting_value = ? WHERE setting_key = 'email_verification_enabled'"); - $stmt->execute([$email_verify]); - $message = 'Settings updated successfully'; + + $settings_to_update = [ + 'email_verification_enabled' => $email_verify, + 'smtp_host' => $_POST['smtp_host'] ?? '', + 'smtp_port' => $_POST['smtp_port'] ?? '587', + 'smtp_user' => $_POST['smtp_user'] ?? '', + 'smtp_pass' => $_POST['smtp_pass'] ?? '', + 'smtp_secure' => $_POST['smtp_secure'] ?? 'tls', + 'mail_from_email' => $_POST['mail_from_email'] ?? '', + 'mail_from_name' => $_POST['mail_from_name'] ?? 'Byro Exchange' + ]; + + foreach ($settings_to_update as $key => $value) { + $stmt = db()->prepare("INSERT INTO system_settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)"); + $stmt->execute([$key, $value]); + } + + $message = '设置已更新'; } $email_verify_enabled = getSetting('email_verification_enabled', '0') === '1'; +$smtp_host = getSetting('smtp_host', ''); +$smtp_port = getSetting('smtp_port', '587'); +$smtp_user = getSetting('smtp_user', ''); +$smtp_pass = getSetting('smtp_pass', ''); +$smtp_secure = getSetting('smtp_secure', 'tls'); +$mail_from_email = getSetting('mail_from_email', ''); +$mail_from_name = getSetting('mail_from_name', 'Byro Exchange'); function getSetting($key, $default = null) { $stmt = db()->prepare("SELECT setting_value FROM system_settings WHERE setting_key = ?"); @@ -25,32 +47,96 @@ function getSetting($key, $default = null) { return $row ? $row['setting_value'] : $default; } -include __DIR__ . '/../includes/header.php'; +ob_start(); ?> -
-
-

Admin Settings

- -
- +
+
+
+
+
注册与邮件设置
- +
+ + + + +
+
+ +
+ > + +
+
开启后,用户在注册页面必须通过验证码验证。测试环境默认验证码:123456
+
+ +
+ +
SMTP 邮件服务设置
+ +
+
+ + +
+
+ + +
+ +
+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ +
+
+
+
-
-
-
- style="width: 20px; height: 20px;"> - -
-

- If enabled, users will see an "Email Verification Code" field during registration. - (Demo code is 123456) -

- -
+
+
关于短信验证
+

+ 目前系统通过邮件服务发送验证码。手机号注册将同样通过绑定的邮件或系统预设通道发送。如需接入特定短信网关,请联系技术支持对接 API。 +

- + diff --git a/api.php b/api.php index 42fcf01..a8e5dc1 100644 --- a/api.php +++ b/api.php @@ -8,43 +8,43 @@ require_once __DIR__ . '/includes/header.php';
-

Introduction

-

Welcome to the Byro API. Our API allows you to access market data, manage your account, and execute trades programmatically. We use a RESTful architecture with JSON responses.

+

+

-

Authentication

-

All private endpoints require API Key authentication. You can generate API keys in your account profile settings.

+

+

Authorization: Bearer YOUR_API_KEY
-

Market Data

-
Get Ticker
+

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

Returns the latest price and 24h volume for the specified symbol.

+

-

Trade

-
Place Order
+

+
POST /api/v1/trade/order
-

Payload example:

+

{
   "symbol": "BTCUSDT",
   "side": "buy",
diff --git a/api/chat.php b/api/chat.php
index 275522e..3772e53 100644
--- a/api/chat.php
+++ b/api/chat.php
@@ -72,7 +72,8 @@ if ($action === 'send_message') {
 
     $stmt = db()->prepare("INSERT INTO messages (user_id, sender, message, ip_address) VALUES (?, ?, ?, ?)");
     $stmt->execute([$user_id, 'user', $message, $ip]);
-    echo json_encode(['success' => true]);
+    $newId = db()->lastInsertId();
+    echo json_encode(['success' => true, 'id' => $newId]);
     exit;
 }
 
@@ -88,7 +89,8 @@ if ($action === 'admin_send') {
 
     $stmt = db()->prepare("INSERT INTO messages (user_id, admin_id, sender, message, ip_address) VALUES (?, ?, ?, ?, ?)");
     $stmt->execute([$user_id, $admin_id, $sender, $message, $target_ip]);
-    echo json_encode(['success' => true]);
+    $newId = db()->lastInsertId();
+    echo json_encode(['success' => true, 'id' => $newId]);
     exit;
 }
 
diff --git a/api/finance.php b/api/finance.php
index ad834c7..14024ef 100644
--- a/api/finance.php
+++ b/api/finance.php
@@ -1,5 +1,6 @@
  $o['id'],
                 'time' => $o['created_at'],
                 'pair' => $o['symbol'] . '/USDT',
-                'type' => 'Binary',
-                'side' => ($o['direction'] === 'up' || $o['direction'] === 'buy') ? 'Buy Up' : 'Buy Down',
+                'type' => __('trade_binary'),
+                'type_raw' => 'binary',
+                'side' => ($o['direction'] === 'up' || $o['direction'] === 'buy') ? __('buy_up') : __('buy_down'),
                 'side_type' => ($o['direction'] === 'up' || $o['direction'] === 'buy') ? 'up' : 'down',
                 'price' => $o['entry_price'],
                 'amount' => $o['amount'],
                 'pnl' => $o['status'] === 'won' ? (float)($o['amount'] * $o['profit_rate'] / 100) : ($o['status'] === 'lost' ? -(float)$o['amount'] : 0),
                 'total' => $o['status'] === 'won' ? (float)($o['amount'] + ($o['amount'] * $o['profit_rate'] / 100)) : ($o['status'] === 'lost' ? 0.00 : '---'),
-                'status' => ($o['status'] === 'won' ? 'Profit' : ($o['status'] === 'lost' ? 'Loss' : 'Executing')),
+                'status' => ($o['status'] === 'won' ? __('won') : ($o['status'] === 'lost' ? __('loss') : __('executing'))),
+                'status_type' => $o['status'] === 'pending' ? 'executing' : $o['status'],
                 'profitRate' => $o['profit_rate']
             ];
             if ($o['status'] === 'pending') {
-                $row['status'] = 'Executing';
+                $row['status'] = __('executing');
                 $row['totalSeconds'] = $o['duration'];
                 $elapsed = time() - strtotime($o['created_at']);
                 $row['secondsLeft'] = max(0, $o['duration'] - $elapsed);
@@ -108,13 +111,15 @@ if ($action === 'get_orders') {
                 'id' => $o['id'],
                 'time' => $o['created_at'],
                 'pair' => $o['symbol'] . '/USDT',
-                'type' => 'Spot',
-                'side' => ucfirst($o['side']),
+                'type' => __('trade_spot'),
+                'type_raw' => 'spot',
+                'side' => $o['side'] === 'buy' ? __('buy') : __('sell'),
                 'side_type' => $o['side'],
                 'price' => $o['price'],
                 'amount' => $o['amount'],
                 'total' => ($o['price'] * $o['amount']),
-                'status' => ucfirst($o['status'])
+                'status' => $o['status'] === 'filled' ? __('approved') : __('pending'),
+                'status_type' => $o['status']
             ];
             if ($o['status'] === 'pending') $open[] = $row;
             else $settlement[] = $row;
@@ -128,14 +133,16 @@ if ($action === 'get_orders') {
                 'id' => $o['id'],
                 'time' => $o['created_at'],
                 'pair' => $o['symbol'] . '/USDT',
-                'type' => 'Contract',
-                'side' => ucfirst($o['direction']),
+                'type' => __('trade_contract'),
+                'type_raw' => 'contract',
+                'side' => $o['direction'] === 'long' ? __('long') : __('short'),
                 'side_type' => $o['direction'] === 'long' ? 'up' : 'down',
                 'price' => $o['entry_price'],
                 'amount' => $o['amount'],
                 'pnl' => $o['profit'],
                 'total' => ($o['amount'] / $o['leverage']) + $o['profit'],
-                'status' => ucfirst($o['status'])
+                'status' => $o['status'] === 'open' ? __('executing') : ($o['profit'] >= 0 ? __('won') : __('loss')),
+                'status_type' => $o['status'] === 'open' ? 'executing' : ($o['profit'] >= 0 ? 'won' : 'loss')
             ];
             if ($o['status'] === 'open') $open[] = $row;
             else $settlement[] = $row;
diff --git a/app.php b/app.php
index c743481..8a5fc13 100644
--- a/app.php
+++ b/app.php
@@ -2,52 +2,269 @@
 require_once __DIR__ . '/includes/lang.php';
 require_once __DIR__ . '/includes/header.php';
 ?>
-
-
-
-

-

- -
- - -
-
Download on the
-
App Store
+
+ +
+
+
+ -
-
-
- QR Code -

Scan to Download

+
+
+ QR +
+
+
+

+
-
-
    -
  • Real-time alerts
  • -
  • Full trading features
  • -
  • 2FA security
  • -
  • 24/7 Live chat
  • -
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+
+
-
-
-
- +
+ + +
+
+
+
+
+
+ +
+

+

+
+
+
+
+
+ +
+

+

+
+
+
+
+
+ +
+

+

+
+
-
+
+ + + + + diff --git a/assets/pasted-20260218-092326-d1106483.png b/assets/pasted-20260218-092326-d1106483.png new file mode 100644 index 0000000..61234a1 Binary files /dev/null and b/assets/pasted-20260218-092326-d1106483.png differ diff --git a/assets/pasted-20260218-122005-f3b20f13.png b/assets/pasted-20260218-122005-f3b20f13.png new file mode 100644 index 0000000..5ee36b2 Binary files /dev/null and b/assets/pasted-20260218-122005-f3b20f13.png differ diff --git a/assets/pasted-20260218-122939-e40f3181.png b/assets/pasted-20260218-122939-e40f3181.png new file mode 100644 index 0000000..c7da84b Binary files /dev/null and b/assets/pasted-20260218-122939-e40f3181.png differ diff --git a/auth/login.php b/auth/login.php index 5bead9a..13a4d28 100644 --- a/auth/login.php +++ b/auth/login.php @@ -9,7 +9,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $password = $_POST['password'] ?? ''; if (empty($account) || empty($password)) { - $error = 'Please fill in all fields'; + $error = __('fill_full_info'); } else { $stmt = db()->prepare("SELECT * FROM users WHERE username = ? OR email = ?"); $stmt->execute([$account, $account]); @@ -28,7 +28,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { exit; } } else { - $error = 'Invalid account or password'; + $error = __('invalid_account_pwd'); } } } diff --git a/auth/register.php b/auth/register.php index 95dc517..b52595f 100644 --- a/auth/register.php +++ b/auth/register.php @@ -26,15 +26,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $error = __('fill_full_info'); } elseif ($password !== $confirm_password) { $error = __('pwd_mismatch'); - } elseif ($email_verify_enabled && $reg_type === 'email' && empty($verify_code)) { - $error = __('enter_verify_code') ?? 'Please enter verification code'; + } elseif ($email_verify_enabled && empty($verify_code)) { + $error = __('enter_verify_code'); } elseif (!$agree_all) { - $error = __('agree_terms_error') ?? 'Please agree to terms'; + $error = __('agree_terms_error'); } else { - if ($email_verify_enabled && $reg_type === 'email' && $verify_code !== '123456') { + if ($email_verify_enabled && $verify_code !== '123456') { // Check session for actual code if not demo if (!isset($_SESSION['email_code']) || $verify_code !== $_SESSION['email_code']) { - $error = __('verify_code_error') ?? 'Invalid verification code'; + $error = __('verify_code_error'); } } @@ -71,7 +71,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { header('Location: /'); exit; } catch (PDOException $e) { - $error = '账号已存在或数据库错误'; + $error = __('account_exists'); } } } @@ -260,7 +260,7 @@ function setRegType(type) { label.innerText = ''; input.placeholder = ''; input.type = 'text'; - if (verifyLabel) verifyLabel.innerText = ''; + if (verifyLabel) verifyLabel.innerText = ''; } } diff --git a/fees.php b/fees.php index 40a5fb7..aaef625 100644 --- a/fees.php +++ b/fees.php @@ -7,20 +7,20 @@ require_once __DIR__ . '/includes/header.php';

-

Spot Trading Fees

+

- - - - + + + + - + @@ -47,19 +47,19 @@ require_once __DIR__ . '/includes/header.php';
Tier30d Trading VolumeMaker FeeTaker Fee
VIP 0 (Regular)VIP 0 () < $10,000 0.100% 0.100%
-

Contract Trading Fees

+

- - - + + + - + diff --git a/includes/footer.php b/includes/footer.php index 874883d..eb9e4c9 100644 --- a/includes/footer.php +++ b/includes/footer.php @@ -221,7 +221,7 @@ csFileInput.addEventListener('change', async () => { formData.append('file', file); formData.append('action', 'upload_image'); - appendMessage('user', ' Uploading image...'); + appendMessage('user', ''); try { const resp = await fetch('/api/chat.php', { @@ -256,15 +256,18 @@ csForm.addEventListener('submit', async (e) => { const msg = csInput.value.trim(); if (!msg) return; - appendMessage('user', msg); csInput.value = ''; try { - await fetch('/api/chat.php?action=send_message', { + const resp = await fetch('/api/chat.php?action=send_message', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${encodeURIComponent(msg)}` }); + const data = await resp.json(); + if (data.success) { + pollMessages(); + } } catch (err) { console.error('Failed to send message:', err); } @@ -274,7 +277,7 @@ function appendMessage(sender, text) { const div = document.createElement('div'); div.className = `mb-2 d-flex ${sender === 'user' ? 'justify-content-end' : 'justify-content-start'}`; div.innerHTML = ` -
+
${text}
`; @@ -283,20 +286,23 @@ function appendMessage(sender, text) { } // Polling for new messages -let lastCount = 0; -setInterval(async () => { +let lastMsgId = 0; +async function pollMessages() { if (csBox.classList.contains('d-none')) return; try { const resp = await fetch('/api/chat.php?action=get_messages'); const data = await resp.json(); - if (data && data.length > lastCount) { - // Find only new messages - const newMessages = data.slice(lastCount); - newMessages.forEach(m => appendMessage(m.sender, m.message)); - lastCount = data.length; + if (data && data.length > 0) { + data.forEach(m => { + if (parseInt(m.id) > lastMsgId) { + appendMessage(m.sender, m.message); + lastMsgId = parseInt(m.id); + } + }); } } catch (err) {} -}, 1000); +} +setInterval(pollMessages, 1000);
TierMaker FeeTaker Fee
Regular 0.020% 0.050%