Autosave: 20260218-091722

This commit is contained in:
Flatlogic Bot 2026-02-18 09:17:22 +00:00
parent bb3dee89dd
commit c6e1a23d69
31 changed files with 792 additions and 217 deletions

View File

@ -137,7 +137,7 @@ ob_start();
</div>
</div>
<div class="col-md-4">
<div class="card p-4 border-0 shadow-sm card-dismissible" data-card-id="settings_instructions">
<div class="card p-4 border-0 shadow-sm card-dismissible card-auto-dismiss" data-card-id="settings_instructions">
<h6 class="fw-bold mb-3">使用说明</h6>
<ul class="small text-muted ps-3 mb-0">
<li class="mb-2"><strong>网站名称:</strong>影响浏览器标签页标题。</li>

View File

@ -17,7 +17,16 @@ try {
$expired = $stmt->fetchAll();
foreach ($expired as $o) {
$result = ($o['control_status'] == 1 || $o['user_control'] == 1) ? 'won' : (($o['control_status'] == 2 || $o['user_control'] == 2) ? 'lost' : ((rand(0, 100) > 50) ? 'won' : 'lost'));
$db->prepare("UPDATE binary_orders SET status = ?, settled_at = NOW() WHERE id = ?")->execute([$result, $o['id']]);
// Get a dummy close price if we don't have one (should match the result)
$close_price = $o['entry_price'];
if ($result === 'won') {
$close_price = ($o['direction'] === 'up' || $o['direction'] === 'buy') ? $o['entry_price'] * 1.01 : $o['entry_price'] * 0.99;
} else {
$close_price = ($o['direction'] === 'up' || $o['direction'] === 'buy') ? $o['entry_price'] * 0.99 : $o['entry_price'] * 1.01;
}
$db->prepare("UPDATE binary_orders SET status = ?, close_price = ?, end_at = NOW() WHERE id = ?")->execute([$result, $close_price, $o['id']]);
if ($result === 'won') {
$win_amount = $o['amount'] + ($o['amount'] * $o['profit_rate'] / 100);
$db->prepare("UPDATE user_balances SET available = available + ? WHERE user_id = ? AND symbol = 'USDT'")->execute([$win_amount, $o['user_id']]);
@ -70,6 +79,11 @@ $orders = $stmt->fetchAll();
</div>
</div>
<div class="card p-3 mb-4 border-0 shadow-sm card-dismissible card-auto-dismiss" data-card-id="binary_instructions">
<h6 class="fw-bold mb-2"><i class="bi bi-info-circle me-2"></i>管理提示</h6>
<p class="small text-muted mb-0">在此页面您可以实时监控用户的秒合约订单。对于进行中的订单,您可以手动设置“控赢”或“控亏”来干预交易结果。订单到期后系统会自动根据设置或市场价进行结算。</p>
</div>
<?php if (isset($_GET['msg'])): ?>
<div class="alert alert-success mb-4">控制状态已更新!</div>
<?php endif; ?>

View File

@ -162,8 +162,8 @@ document.getElementById('chat-form').addEventListener('submit', async (e) => {
fetchMessages();
});
setInterval(refreshUsers, 5000);
setInterval(fetchMessages, 2000);
setInterval(refreshUsers, 3000);
setInterval(fetchMessages, 1000);
refreshUsers();
</script>
</body>

View File

@ -48,6 +48,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
->execute([$req['user_id'], $req['amount'], $req['symbol']]);
}
// If withdrawal, update transaction status
if ($req['type'] === 'withdrawal') {
$db->prepare("UPDATE transactions SET status = 'completed' WHERE user_id = ? AND type = 'withdrawal' AND amount = ? AND symbol = ? AND status = 'pending' ORDER BY created_at DESC LIMIT 1")
->execute([$req['user_id'], $req['amount'], $req['symbol']]);
}
$db->commit();
header("Location: finance.php?msg=approved");
} catch (Exception $e) {
@ -69,7 +75,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$db->prepare("UPDATE user_balances SET available = available + ? WHERE user_id = ? AND symbol = ?")
->execute([$req['amount'], $req['user_id'], $req['symbol']]);
$db->prepare("INSERT INTO transactions (user_id, type, amount, symbol, status) VALUES (?, 'withdrawal_refund', ?, ?, 'completed')")
$db->prepare("UPDATE transactions SET status = 'rejected' WHERE user_id = ? AND type = 'withdrawal' AND amount = ? AND symbol = ? AND status = 'pending' ORDER BY created_at DESC LIMIT 1")
->execute([$req['user_id'], $req['amount'], $req['symbol']]);
}
@ -119,6 +125,11 @@ $requests = $stmt->fetchAll();
</div>
</div>
<div class="card p-3 mb-4 border-0 shadow-sm card-dismissible card-auto-dismiss" data-card-id="finance_instructions">
<h6 class="fw-bold mb-2"><i class="bi bi-info-circle me-2"></i>充提管理说明</h6>
<p class="small text-muted mb-0">在此页面您可以审核用户的充值和提现申请。通过充值申请会自动增加用户余额;通过提现申请则完成资产扣除;拒绝提现申请会自动退回冻结金额。</p>
</div>
<?php if (isset($_GET['msg'])): ?>
<div class="alert alert-success mb-4">操作成功!</div>
<?php endif; ?>

View File

@ -74,6 +74,11 @@ if ($user_id) {
<?php endif; ?>
</div>
<div class="card p-3 mb-4 border-0 shadow-sm card-dismissible card-auto-dismiss" data-card-id="kyc_instructions">
<h6 class="fw-bold mb-2"><i class="bi bi-info-circle me-2"></i>实名审核说明</h6>
<p class="small text-muted mb-0">在此页面您可以审核用户的实名认证申请。请仔细对比用户提交的证件照片和填写的身份信息。审核通过后用户将获得认证标识。</p>
</div>
<?php if (isset($_GET['msg'])): ?>
<div class="alert alert-success mb-4">操作成功!</div>
<?php endif; ?>
@ -165,6 +170,30 @@ if ($user_id) {
</div>
</div>
<!-- Reject Modal -->
<div class="modal fade" id="rejectModal" tabindex="-1">
<div class="modal-dialog">
<form class="modal-content" method="POST">
<input type="hidden" name="action" value="reject">
<input type="hidden" name="user_id" id="reject_user_id">
<div class="modal-header">
<h5 class="modal-title">拒绝实名认证</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">拒绝理由</label>
<textarea name="reason" class="form-control" rows="3" required placeholder="请说明拒绝原因..."></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="submit" class="btn btn-danger">确认拒绝</button>
</div>
</form>
</div>
</div>
<style>
.cursor-zoom-in { cursor: zoom-in; }
#viewerImage.zoomed {

View File

@ -152,7 +152,10 @@ function renderAdminPage($content, $title = '后台管理') {
<a href="/admin/index.php" class="nav-link <?= $current_page == 'index.php' ? 'active' : '' ?>"><i class="bi bi-house-door"></i> 首页</a>
<?php if (hasPermission('manage_users')): ?>
<a href="/admin/users.php" class="nav-link <?= $current_page == 'users.php' ? 'active' : '' ?>"><i class="bi bi-people"></i> 玩家管理</a>
<a href="/admin/users.php" class="nav-link <?= $current_page == 'users.php' ? 'active' : '' ?>">
<i class="bi bi-people"></i> 玩家管理
<span class="badge bg-success rounded-pill ms-auto d-none" id="users-badge">0</span>
</a>
<?php endif; ?>
<?php if (!$admin['is_agent']): ?>
@ -174,8 +177,14 @@ function renderAdminPage($content, $title = '后台管理') {
<i class="bi bi-clock"></i> 秒合约管理
<span class="badge bg-info rounded-pill ms-auto d-none" id="binary-badge">0</span>
</a>
<a href="/admin/contract.php" class="nav-link <?= $current_page == 'contract.php' ? 'active' : '' ?>"><i class="bi bi-layers"></i> 永续合约</a>
<a href="/admin/spot.php" class="nav-link <?= $current_page == 'spot.php' ? 'active' : '' ?>"><i class="bi bi-currency-exchange"></i> 币币交易</a>
<a href="/admin/contract.php" class="nav-link <?= $current_page == 'contract.php' ? 'active' : '' ?>">
<i class="bi bi-layers"></i> 永续合约
<span class="badge bg-info rounded-pill ms-auto d-none" id="contract-badge">0</span>
</a>
<a href="/admin/spot.php" class="nav-link <?= $current_page == 'spot.php' ? 'active' : '' ?>">
<i class="bi bi-currency-exchange"></i> 币币交易
<span class="badge bg-info rounded-pill ms-auto d-none" id="spot-badge">0</span>
</a>
<?php endif; ?>
<?php if (hasPermission('manage_kyc')): ?>
@ -189,7 +198,10 @@ function renderAdminPage($content, $title = '后台管理') {
<a href="/admin/exchange.php" class="nav-link"><i class="bi bi-arrow-left-right"></i> 兑换管理</a>
<a href="/admin/mining.php" class="nav-link"><i class="bi bi-cpu"></i> 质押挖矿</a>
<a href="/admin/ai_control.php" class="nav-link"><i class="bi bi-robot"></i> AI控盘</a>
<a href="/admin/customer_service.php" class="nav-link"><i class="bi bi-headset"></i> 客服管理</a>
<a href="/admin/customer_service.php" class="nav-link <?= $current_page == 'customer_service.php' ? 'active' : '' ?>">
<i class="bi bi-headset"></i> 客服管理
<span class="badge bg-warning rounded-pill ms-auto d-none" id="messages-badge">0</span>
</a>
<a href="/admin/backend_settings.php" class="nav-link"><i class="bi bi-gear"></i> 后台设置</a>
<?php endif; ?>
@ -219,14 +231,36 @@ function renderAdminPage($content, $title = '后台管理') {
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Handle dismissible cards
// Handle dismissible cards and badge clearing
document.addEventListener('DOMContentLoaded', function() {
const dismissedCards = JSON.parse(localStorage.getItem('dismissed_admin_cards') || '[]');
const visitedPages = JSON.parse(localStorage.getItem('visited_admin_pages') || '[]');
const currentPage = window.location.pathname;
// Clear badges based on current page
if (currentPage.includes('finance.php')) {
fetch('/api/admin_notifications.php?action=clear&type=finance');
} else if (currentPage.includes('kyc.php')) {
fetch('/api/admin_notifications.php?action=clear&type=kyc');
} else if (currentPage.includes('binary.php')) {
fetch('/api/admin_notifications.php?action=clear&type=binary');
} else if (currentPage.includes('contract.php')) {
fetch('/api/admin_notifications.php?action=clear&type=contract');
} else if (currentPage.includes('spot.php')) {
fetch('/api/admin_notifications.php?action=clear&type=spot');
} else if (currentPage.includes('customer_service.php')) {
fetch('/api/admin_notifications.php?action=clear&type=messages');
} else if (currentPage.includes('users.php')) {
fetch('/api/admin_notifications.php?action=clear&type=users');
}
document.querySelectorAll('.card-dismissible').forEach(card => {
const cardId = card.getAttribute('data-card-id') || window.location.pathname;
if (dismissedCards.includes(cardId)) {
const cardId = card.getAttribute('data-card-id') || currentPage;
// Auto-hide if already dismissed OR if page was visited once and it's marked as auto-dismiss
if (dismissedCards.includes(cardId) || (visitedPages.includes(currentPage) && card.classList.contains('card-auto-dismiss'))) {
card.style.display = 'none';
return;
}
const closeBtn = document.createElement('button');
@ -234,16 +268,32 @@ function renderAdminPage($content, $title = '后台管理') {
closeBtn.style.zIndex = '10';
closeBtn.onclick = function() {
card.style.display = 'none';
dismissedCards.push(cardId);
localStorage.setItem('dismissed_admin_cards', JSON.stringify(dismissedCards));
if (!dismissedCards.includes(cardId)) {
dismissedCards.push(cardId);
localStorage.setItem('dismissed_admin_cards', JSON.stringify(dismissedCards));
}
};
card.style.position = 'relative';
card.appendChild(closeBtn);
});
// Mark current page as visited
if (!visitedPages.includes(currentPage)) {
visitedPages.push(currentPage);
localStorage.setItem('visited_admin_pages', JSON.stringify(visitedPages));
}
});
let lastTotal = 0;
const notificationSound = new Audio('https://assets.mixkit.co/active_storage/sfx/2869/2869-preview.mp3');
let lastSoundTotal = parseInt(sessionStorage.getItem('last_sound_total') || '-1');
function speak(text) {
if ('speechSynthesis' in window) {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'zh-CN';
window.speechSynthesis.speak(utterance);
}
}
function checkNotifications() {
fetch('/api/admin_notifications.php')
@ -252,11 +302,12 @@ function renderAdminPage($content, $title = '后台管理') {
if (data.success) {
const counts = data.counts;
const total = counts.total;
const soundTotal = counts.sound_total || 0;
// Finance badge
const financeBadge = document.getElementById('finance-badge');
if (financeBadge) {
const fCount = counts.recharge + counts.withdrawal;
const fCount = (counts.recharge || 0) + (counts.withdrawal || 0);
if (fCount > 0) {
financeBadge.innerText = fCount;
financeBadge.classList.remove('d-none');
@ -287,6 +338,50 @@ function renderAdminPage($content, $title = '后台管理') {
}
}
// Contract badge
const contractBadge = document.getElementById('contract-badge');
if (contractBadge) {
if (counts.contract > 0) {
contractBadge.innerText = counts.contract;
contractBadge.classList.remove('d-none');
} else {
contractBadge.classList.add('d-none');
}
}
// Spot badge
const spotBadge = document.getElementById('spot-badge');
if (spotBadge) {
if (counts.spot > 0) {
spotBadge.innerText = counts.spot;
spotBadge.classList.remove('d-none');
} else {
spotBadge.classList.add('d-none');
}
}
// Users badge
const usersBadge = document.getElementById('users-badge');
if (usersBadge) {
if (counts.users > 0) {
usersBadge.innerText = counts.users;
usersBadge.classList.remove('d-none');
} else {
usersBadge.classList.add('d-none');
}
}
// Messages badge
const messagesBadge = document.getElementById('messages-badge');
if (messagesBadge) {
if (counts.messages > 0) {
messagesBadge.innerText = counts.messages;
messagesBadge.classList.remove('d-none');
} else {
messagesBadge.classList.add('d-none');
}
}
// Total badge
const totalBadge = document.getElementById('total-badge');
if (totalBadge) {
@ -298,10 +393,12 @@ function renderAdminPage($content, $title = '后台管理') {
}
}
if (total > lastTotal) {
notificationSound.play().catch(e => console.log('Audio play failed:', e));
if (lastSoundTotal !== -1 && soundTotal > lastSoundTotal) {
speak("你有新的消息,请注意查收");
}
lastTotal = total;
lastSoundTotal = soundTotal;
sessionStorage.setItem('last_sound_total', lastSoundTotal);
}
})
.catch(e => console.error('Notification check failed:', e));

View File

@ -154,6 +154,11 @@ ob_start();
</button>
</div>
<div class="card p-3 mb-4 border-0 shadow-sm card-dismissible card-auto-dismiss" data-card-id="users_instructions">
<h6 class="fw-bold mb-2"><i class="bi bi-people me-2"></i>用户管理提示</h6>
<p class="small text-muted mb-0">您可以在此查看所有注册用户的信息。通过“编辑”功能,您可以手动调整用户余额、重置密码、修改实名信息或设置全局胜率控制。点击“记录”可查看该用户的详细交易历史。</p>
</div>
<?php if (isset($_GET['msg'])): ?>
<?php if ($_GET['msg'] === 'duplicate'): ?>
<div class="alert alert-danger alert-dismissible fade show mb-4" role="alert">

View File

@ -17,41 +17,75 @@ $stmt = $db->prepare("SELECT is_agent FROM admins WHERE id = ?");
$stmt->execute([$admin_id]);
$admin = $stmt->fetch();
$action = $_GET['action'] ?? '';
if ($action === 'clear') {
$type = $_GET['type'] ?? '';
if ($type) {
$_SESSION['admin_cleared_' . $type] = time();
}
echo json_encode(['success' => true]);
exit;
}
$pending_recharge = 0;
$pending_withdrawal = 0;
$pending_kyc = 0;
$active_binary = 0;
$active_spot = 0;
$active_contract = 0;
$new_messages = 0;
$new_registrations = 0;
$cleared_recharge = $_SESSION['admin_cleared_finance'] ?? 0;
$cleared_kyc = $_SESSION['admin_cleared_kyc'] ?? 0;
$cleared_binary = $_SESSION['admin_cleared_binary'] ?? 0;
$cleared_spot = $_SESSION['admin_cleared_spot'] ?? 0;
$cleared_contract = $_SESSION['admin_cleared_contract'] ?? 0;
$cleared_messages = $_SESSION['admin_cleared_messages'] ?? 0;
$cleared_users = $_SESSION['admin_cleared_users'] ?? 0;
function getCount($db, $sql, $params) {
$stmt = $db->prepare($sql);
$stmt->execute($params);
return (int)$stmt->fetchColumn();
}
if ($admin['is_agent']) {
$pending_recharge = $db->prepare("SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'recharge' AND r.status = 'pending' AND u.agent_id = ?");
$pending_recharge->execute([$admin_id]);
$pending_recharge = $pending_recharge->fetchColumn();
$pending_withdrawal = $db->prepare("SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'withdrawal' AND r.status = 'pending' AND u.agent_id = ?");
$pending_withdrawal->execute([$admin_id]);
$pending_withdrawal = $pending_withdrawal->fetchColumn();
$pending_kyc = $db->prepare("SELECT COUNT(*) FROM users WHERE kyc_status = 'pending' AND agent_id = ?");
$pending_kyc->execute([$admin_id]);
$pending_kyc = $pending_kyc->fetchColumn();
$active_binary = $db->prepare("SELECT COUNT(*) FROM binary_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND u.agent_id = ?");
$active_binary->execute([$admin_id]);
$active_binary = $active_binary->fetchColumn();
$agent_id = $admin_id;
$pending_recharge = getCount($db, "SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'recharge' AND r.status = 'pending' AND u.agent_id = ? AND UNIX_TIMESTAMP(r.created_at) > ?", [$agent_id, $cleared_recharge]);
$pending_withdrawal = getCount($db, "SELECT COUNT(*) FROM finance_requests r JOIN users u ON r.user_id = u.id WHERE r.type = 'withdrawal' AND r.status = 'pending' AND u.agent_id = ? AND UNIX_TIMESTAMP(r.created_at) > ?", [$agent_id, $cleared_recharge]);
$pending_kyc = getCount($db, "SELECT COUNT(*) FROM users WHERE kyc_status = 1 AND agent_id = ? AND UNIX_TIMESTAMP(created_at) > ?", [$agent_id, $cleared_kyc]);
$active_binary = getCount($db, "SELECT COUNT(*) FROM binary_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND u.agent_id = ? AND UNIX_TIMESTAMP(o.created_at) > ?", [$agent_id, $cleared_binary]);
$active_spot = getCount($db, "SELECT COUNT(*) FROM spot_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND u.agent_id = ? AND UNIX_TIMESTAMP(o.created_at) > ?", [$agent_id, $cleared_spot]);
$active_contract = getCount($db, "SELECT COUNT(*) FROM contract_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'open' AND u.agent_id = ? AND UNIX_TIMESTAMP(o.created_at) > ?", [$agent_id, $cleared_contract]);
$new_messages = getCount($db, "SELECT COUNT(*) FROM messages m JOIN users u ON m.user_id = u.id WHERE m.sender = 'user' AND u.agent_id = ? AND UNIX_TIMESTAMP(m.created_at) > ?", [$agent_id, $cleared_messages]);
$new_registrations = getCount($db, "SELECT COUNT(*) FROM users WHERE agent_id = ? AND UNIX_TIMESTAMP(created_at) > ?", [$agent_id, $cleared_users]);
} else {
$pending_recharge = $db->query("SELECT COUNT(*) FROM finance_requests WHERE type = 'recharge' AND status = 'pending'")->fetchColumn();
$pending_withdrawal = $db->query("SELECT COUNT(*) FROM finance_requests WHERE type = 'withdrawal' AND status = 'pending'")->fetchColumn();
$pending_kyc = $db->query("SELECT COUNT(*) FROM users WHERE kyc_status = 'pending'")->fetchColumn();
$active_binary = $db->query("SELECT COUNT(*) FROM binary_orders WHERE status = 'pending'")->fetchColumn();
$pending_recharge = getCount($db, "SELECT COUNT(*) FROM finance_requests WHERE type = 'recharge' AND status = 'pending' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_recharge]);
$pending_withdrawal = getCount($db, "SELECT COUNT(*) FROM finance_requests WHERE type = 'withdrawal' AND status = 'pending' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_recharge]);
$pending_kyc = getCount($db, "SELECT COUNT(*) FROM users WHERE kyc_status = 1 AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_kyc]);
$active_binary = getCount($db, "SELECT COUNT(*) FROM binary_orders WHERE status = 'pending' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_binary]);
$active_spot = getCount($db, "SELECT COUNT(*) FROM spot_orders WHERE status = 'pending' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_spot]);
$active_contract = getCount($db, "SELECT COUNT(*) FROM contract_orders WHERE status = 'open' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_contract]);
$new_messages = getCount($db, "SELECT COUNT(*) FROM messages WHERE sender = 'user' AND UNIX_TIMESTAMP(created_at) > ?", [$cleared_messages]);
$new_registrations = getCount($db, "SELECT COUNT(*) FROM users WHERE UNIX_TIMESTAMP(created_at) > ?", [$cleared_users]);
}
$total = $pending_recharge + $pending_withdrawal + $pending_kyc + $active_binary + $active_spot + $active_contract + $new_messages + $new_registrations;
$sound_trigger_count = $pending_recharge + $pending_withdrawal + $new_messages + $new_registrations;
echo json_encode([
'success' => true,
'counts' => [
'recharge' => (int)$pending_recharge,
'withdrawal' => (int)$pending_withdrawal,
'kyc' => (int)$pending_kyc,
'binary' => (int)$active_binary,
'total' => (int)$pending_recharge + (int)$pending_withdrawal + (int)$pending_kyc + (int)$active_binary
'recharge' => $pending_recharge,
'withdrawal' => $pending_withdrawal,
'kyc' => $pending_kyc,
'binary' => $active_binary,
'spot' => $active_spot,
'contract' => $active_contract,
'messages' => $new_messages,
'users' => $new_registrations,
'total' => $total,
'sound_total' => $sound_trigger_count
]
]);

View File

@ -115,7 +115,7 @@ if ($action === 'settle_order') {
$db->beginTransaction();
try {
$db->prepare("UPDATE binary_orders SET close_price = ?, status = ?, settled_at = NOW() WHERE id = ?")
$db->prepare("UPDATE binary_orders SET close_price = ?, status = ?, end_at = NOW() WHERE id = ?")
->execute([$close_price, $result, $order_id]);
if ($result === 'won') {

View File

@ -45,15 +45,37 @@ if ($action === 'upload_image' || (isset($_POST['action']) && $_POST['action'] =
if ($action === 'get_messages') {
$user_id = $_SESSION['user_id'] ?? 0;
// For simplicity, we get all messages for this user session or UID
// If not logged in, we could use session_id or IP, but let's stick to user_id or all recent for the session
$stmt = db()->prepare("SELECT * FROM messages WHERE user_id = ? OR (user_id = 0 AND ip_address = ?) ORDER BY created_at ASC");
$stmt->execute([$user_id, $_SERVER['REMOTE_ADDR']]);
$target_user_id = $_GET['user_id'] ?? $user_id;
$target_ip = $_GET['ip'] ?? $_SERVER['REMOTE_ADDR'];
// If admin is requesting, we use the provided user_id and ip
if (isset($_SESSION['admin_id'])) {
$stmt = db()->prepare("SELECT * FROM messages WHERE (user_id = ? AND user_id != 0) OR (user_id = 0 AND ip_address = ?) ORDER BY created_at ASC");
$stmt->execute([$target_user_id, $target_ip]);
} else {
// User requesting their own messages
$stmt = db()->prepare("SELECT * FROM messages WHERE (user_id = ? AND user_id != 0) OR (user_id = 0 AND ip_address = ?) ORDER BY created_at ASC");
$stmt->execute([$user_id, $_SERVER['REMOTE_ADDR']]);
}
$messages = $stmt->fetchAll();
echo json_encode($messages);
exit;
}
if ($action === 'send_message') {
$message = $_POST['message'] ?? '';
if (!$message) exit(json_encode(['success' => false]));
$user_id = $_SESSION['user_id'] ?? 0;
$ip = $_SERVER['REMOTE_ADDR'];
$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]);
exit;
}
if ($action === 'admin_send') {
$message = $_POST['message'] ?? '';
$user_id = $_POST['user_id'] ?? 0;
@ -61,7 +83,7 @@ if ($action === 'admin_send') {
if (!$message) exit(json_encode(['success' => false]));
$admin_id = $_SESSION['user_id'] ?? 1; // Default to admin
$admin_id = $_SESSION['admin_id'] ?? 1;
$sender = 'admin';
$stmt = db()->prepare("INSERT INTO messages (user_id, admin_id, sender, message, ip_address) VALUES (?, ?, ?, ?, ?)");

View File

@ -42,13 +42,21 @@ if ($action === 'get_orders') {
if ($o['control_status'] == 1 || $o['user_control'] == 1) $result = 'won';
elseif ($o['control_status'] == 2 || $o['user_control'] == 2) $result = 'lost';
else {
// Natural result fallback (randomized or tie-breaker if price history unavailable)
// Natural result fallback
$result = (rand(0, 100) > 50) ? 'won' : 'lost';
}
// Dummy close price
$close_price = $o['entry_price'];
if ($result === 'won') {
$close_price = ($o['direction'] === 'up' || $o['direction'] === 'buy') ? $o['entry_price'] * 1.01 : $o['entry_price'] * 0.99;
} else {
$close_price = ($o['direction'] === 'up' || $o['direction'] === 'buy') ? $o['entry_price'] * 0.99 : $o['entry_price'] * 1.01;
}
$db->beginTransaction();
try {
$db->prepare("UPDATE binary_orders SET status = ?, settled_at = NOW() WHERE id = ?")->execute([$result, $order_id]);
$db->prepare("UPDATE binary_orders SET status = ?, close_price = ?, end_at = NOW() WHERE id = ?")->execute([$result, $close_price, $order_id]);
if ($result === 'won') {
$win_amount = $o['amount'] + ($o['amount'] * $o['profit_rate'] / 100);
$db->prepare("UPDATE user_balances SET available = available + ? WHERE user_id = ? AND symbol = 'USDT'")->execute([$win_amount, $user_id]);
@ -75,8 +83,8 @@ if ($action === 'get_orders') {
'side_type' => ($o['direction'] === 'up' || $o['direction'] === 'buy') ? 'up' : 'down',
'price' => $o['entry_price'],
'amount' => $o['amount'],
'pnl' => $o['status'] === 'won' ? ($o['amount'] * $o['profit_rate'] / 100) : ($o['status'] === 'lost' ? -$o['amount'] : 0),
'total' => $o['status'] === 'won' ? ($o['amount'] + ($o['amount'] * $o['profit_rate'] / 100)) : ($o['status'] === 'lost' ? '0.00' : '---'),
'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')),
'profitRate' => $o['profit_rate']
];

View File

@ -128,25 +128,107 @@ a:hover {
padding-right: 15px;
}
.display-3 {
font-size: 2.5rem;
font-size: 2.2rem;
font-weight: 800;
line-height: 1.2;
}
.display-4 {
font-size: 2rem;
font-size: 1.8rem;
font-weight: 700;
}
.card {
border-radius: 12px !important;
border-radius: 16px !important;
border: 1px solid rgba(255, 255, 255, 0.05) !important;
margin-bottom: 15px;
}
.card-body {
padding: 1.25rem !important;
}
.btn {
padding: 12px 20px;
border-radius: 10px;
border-radius: 12px;
font-size: 14px;
}
header {
height: 60px;
padding: 0 15px;
background: rgba(11, 14, 17, 0.95) !important;
}
.logo-text {
font-size: 18px;
letter-spacing: 0 !important;
}
.logo-container {
gap: 8px;
}
/* Better spacing for sections on mobile */
.section {
padding: 40px 0;
}
/* Improve table visibility on mobile */
.table-container {
padding: 10px;
border-radius: 12px;
overflow-x: auto;
}
/* App-like feel for mobile */
body {
padding-bottom: 75px; /* Space for bottom nav */
}
.nav-tabs {
flex-wrap: nowrap;
overflow-x: auto;
scrollbar-width: none;
border-bottom: 1px solid var(--border);
}
.nav-tabs::-webkit-scrollbar { display: none; }
.nav-tabs .nav-link {
white-space: nowrap;
padding: 10px 15px;
}
/* Fixed Bottom Navigation for App-like experience */
.mobile-bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 65px;
background: rgba(18, 21, 25, 0.95);
backdrop-filter: blur(15px);
display: flex;
justify-content: space-around;
align-items: center;
border-top: 1px solid var(--border);
z-index: 1000;
padding-bottom: env(safe-area-inset-bottom);
}
.mobile-bottom-nav a {
display: flex;
flex-direction: column;
align-items: center;
text-decoration: none;
color: var(--text-muted);
font-size: 11px;
gap: 4px;
flex: 1;
}
.mobile-bottom-nav a i {
font-size: 20px;
}
.mobile-bottom-nav a.active {
color: var(--primary);
}
/* Responsive grids */
.row > * {
padding-right: 10px !important;
padding-left: 10px !important;
}
}
/* Custom Scrollbar */

View File

@ -659,7 +659,85 @@
.kline-container { min-height: 400px; height: 400px; }
.cycle-grid { grid-template-columns: repeat(3, 1fr); }
.cycle-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; }
/* Mobile Switcher Module */
.mobile-type-switcher {
padding: 12px 15px;
background: #0b0e11;
border-bottom: 1px solid var(--term-border);
}
.switcher-module {
display: flex;
background: #1e2329;
padding: 4px;
border-radius: 12px;
gap: 4px;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);
}
.switcher-item {
flex: 1;
text-align: center;
padding: 10px 5px;
border-radius: 10px;
text-decoration: none;
color: var(--term-muted);
font-size: 13px;
font-weight: 700;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
align-items: center;
justify-content: center;
}
.switcher-item.active {
background: linear-gradient(135deg, #0062ff, #00d2ff);
color: #fff;
box-shadow: 0 4px 10px rgba(0, 98, 255, 0.3);
}
/* Overall Mobile Tidiness */
.terminal-header {
height: 60px;
padding: 0 15px;
}
.terminal-chart {
height: 380px !important;
}
.trading-panels {
padding: 15px;
background: #0b0e11;
border-top: 1px solid var(--term-border);
}
.binary-order-panel .btn-buy-sell {
height: 50px;
font-size: 14px;
border-radius: 10px;
}
.cycle-btn {
min-height: 45px;
border-radius: 10px;
}
.cycle-btn .cycle-time { font-size: 12px; }
.cycle-btn .cycle-profit { font-size: 10px; }
.amount-input-wrapper .form-control {
height: 45px;
font-size: 16px;
}
.quick-amounts .btn {
height: 35px;
font-size: 12px;
padding: 0;
}
}
/* Popup */

BIN
assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -17,7 +17,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($user && password_verify($password, $user['password_hash'])) {
if ($user['role'] === 'admin') {
$error = '管理员请通过后台页面登录';
$error = __('login_admin_error');
} else {
if (session_status() === PHP_SESSION_NONE) session_start();
$_SESSION['user_id'] = $user['id'];

View File

@ -23,18 +23,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$agree_all = isset($_POST['agree_all']);
if (empty($account) || empty($password)) {
$error = '请填写完整信息';
$error = __('fill_full_info');
} elseif ($password !== $confirm_password) {
$error = '两次输入的密码不一致';
$error = __('pwd_mismatch');
} elseif ($email_verify_enabled && $reg_type === 'email' && empty($verify_code)) {
$error = '请输入邮箱验证码';
$error = __('enter_verify_code') ?? 'Please enter verification code';
} elseif (!$agree_all) {
$error = '请勾选并同意服务协议和隐私政策';
$error = __('agree_terms_error') ?? 'Please agree to terms';
} else {
if ($email_verify_enabled && $reg_type === 'email' && $verify_code !== '123456') {
// Check session for actual code if not demo
if (!isset($_SESSION['email_code']) || $verify_code !== $_SESSION['email_code']) {
$error = '验证码错误';
$error = __('verify_code_error') ?? 'Invalid verification code';
}
}
@ -82,7 +82,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'send_code') {
header('Content-Type: application/json');
$email = $_GET['email'] ?? '';
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo json_encode(['success' => false, 'error' => '无效的邮箱地址']);
echo json_encode(['success' => false, 'error' => __('invalid_email')]);
exit;
}
@ -91,7 +91,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'send_code') {
$_SESSION['email_code'] = $code;
require_once __DIR__ . '/../mail/MailService.php';
$res = MailService::sendMail($email, '验证码 - Byro Registration', "您的验证码是: $code", "Your verification code is: $code");
$res = MailService::sendMail($email, (__('verification_code') . ' - Byro Registration'), (__('verification_code') . ": $code"), "Your verification code is: $code");
echo json_encode(['success' => true]);
exit;
@ -123,6 +123,7 @@ include __DIR__ . '/../includes/header.php';
border-color: var(--primary) !important;
box-shadow: 0 0 0 4px rgba(0, 98, 255, 0.1) !important;
background: rgba(0, 0, 0, 0.5) !important;
border-radius: 12px;
}
.form-label {
font-size: 14px !important;
@ -228,11 +229,11 @@ include __DIR__ . '/../includes/header.php';
<div class="mb-4 form-check small">
<input type="checkbox" name="agree_all" class="form-check-input bg-black border-secondary" id="agreeCheck" required>
<label class="form-check-label text-white fw-medium" for="agreeCheck">
我已阅读并同意 <a href="/tos.php" target="_blank" class="text-primary text-decoration-none fw-bold">《服务协议》</a> <a href="/legal.php" target="_blank" class="text-primary text-decoration-none fw-bold">《隐私政策》</a>
<?= __('agree_tos_privacy') ?>
</label>
</div>
<button type="submit" class="btn btn-primary w-100 py-3 fw-bold rounded-pill mb-4 shadow-primary">立即注册</button>
<button type="submit" class="btn btn-primary w-100 py-3 fw-bold rounded-pill mb-4 shadow-primary"><?= __('register_now') ?></button>
<div class="text-center small text-muted">
<?= __('have_account') ?> <a href="/auth/login.php" class="text-primary fw-bold text-decoration-none"><?= __('login') ?></a>
@ -259,14 +260,14 @@ function setRegType(type) {
label.innerText = '<?= __('mobile_number') ?>';
input.placeholder = '<?= __('mobile_number') ?>';
input.type = 'text';
if (verifyLabel) verifyLabel.innerText = '<?= __('mobile_verify') ?? '验证码' ?>';
if (verifyLabel) verifyLabel.innerText = '<?= __('mobile_verify') ?? __('verification_code') ?>';
}
}
function sendCode() {
const email = document.getElementById('account-input').value;
if (!email || !email.includes('@')) {
alert('请输入有效的邮箱地址');
alert('<?= __('invalid_email') ?>');
return;
}
@ -283,12 +284,12 @@ function sendCode() {
btn.innerText = seconds + 's';
if (seconds <= 0) {
clearInterval(timer);
btn.innerText = '重新发送';
btn.innerText = '<?= __('resend') ?>';
btn.disabled = false;
}
}, 1000);
} else {
alert(data.error || '发送失败');
alert(data.error || '<?= __('send_failed') ?>');
btn.disabled = false;
}
});

39
cookie-policy.php Normal file
View File

@ -0,0 +1,39 @@
<?php
require_once __DIR__ . '/includes/lang.php';
require_once __DIR__ . '/db/config.php';
$site_name = 'Byro';
$site_logo = '';
try {
$stmt = db()->prepare("SELECT setting_value FROM system_settings WHERE setting_key = 'site_name'");
$stmt->execute();
$site_name = $stmt->fetchColumn() ?: 'Byro';
$stmt = db()->prepare("SELECT setting_value FROM system_settings WHERE setting_key = 'site_logo'");
$stmt->execute();
$site_logo = $stmt->fetchColumn() ?: '';
} catch (Exception $e) {}
$title = __('cookie_policy_title');
require_once __DIR__ . '/includes/header.php';
?>
<main class="container my-5 pt-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card border-secondary shadow-lg" style="background: rgba(26, 30, 35, 0.95); backdrop-filter: blur(10px);">
<div class="card-body p-4 p-md-5">
<h1 class="mb-4 text-primary fw-bold"><?= __('cookie_policy_title') ?></h1>
<div class="text-light lh-lg fs-5">
<?= __('cookie_policy_content') ?>
</div>
<div class="mt-5 pt-4 border-top border-secondary">
<a href="/" class="btn btn-outline-primary"><?= __('home') ?></a>
</div>
</div>
</div>
</div>
</div>
</main>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -3,14 +3,18 @@
<div class="row g-4 mb-5">
<div class="col-lg-4 col-md-12">
<div class="logo-container mb-3">
<div class="logo-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7L12 12L22 7L12 2Z" fill="white"/>
<path d="M2 17L12 22L22 17" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 12L12 17L22 12" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<span class="logo-text">Byro</span>
<?php if ($site_logo): ?>
<img src="<?= $site_logo ?>" height="30" class="me-2">
<?php else: ?>
<div class="logo-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7L12 12L22 7L12 2Z" fill="white"/>
<path d="M2 17L12 22L22 17" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 12L12 17L22 12" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<?php endif; ?>
<span class="logo-text"><?= $site_name ?></span>
</div>
<p class="text-muted small mb-4">
<?= __('footer_desc') ?>
@ -95,32 +99,47 @@
bottom: 0;
left: 0;
width: 100%;
height: 65px;
height: 70px;
display: flex;
justify-content: space-around;
align-items: center;
z-index: 10000;
padding-bottom: env(safe-area-inset-bottom);
background: rgba(18, 18, 18, 0.95) !important;
backdrop-filter: blur(10px);
background: rgba(30, 35, 41, 0.98) !important;
border-top: 1px solid rgba(255, 255, 255, 0.05) !important;
backdrop-filter: blur(15px);
box-shadow: 0 -5px 20px rgba(0,0,0,0.3);
}
.mobile-nav a {
display: flex;
flex-direction: column;
align-items: center;
text-decoration: none;
color: var(--text-muted);
font-size: 11px;
text-decoration: none !important;
color: #848e9c;
font-size: 10px;
font-weight: 500;
transition: all 0.3s;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
flex: 1;
padding: 10px 0;
}
.mobile-nav a i {
font-size: 20px;
margin-bottom: 2px;
font-size: 22px;
margin-bottom: 3px;
transition: transform 0.2s;
}
.mobile-nav a.active {
color: var(--primary);
}
.mobile-nav a.active i {
transform: translateY(-2px);
}
.mobile-nav a span {
transform: scale(0.9);
}
.mobile-nav a.active span {
transform: scale(1);
font-weight: 700;
}
/* Hide desktop elements on mobile if needed */
@media (max-width: 768px) {
body { padding-bottom: 80px; }
@ -271,12 +290,13 @@ setInterval(async () => {
const resp = await fetch('/api/chat.php?action=get_messages');
const data = await resp.json();
if (data && data.length > lastCount) {
csMessages.innerHTML = '<div class="text-center text-muted small mb-3">Welcome to Byro Support! How can we help?</div>';
data.forEach(m => appendMessage(m.sender, m.message));
// Find only new messages
const newMessages = data.slice(lastCount);
newMessages.forEach(m => appendMessage(m.sender, m.message));
lastCount = data.length;
}
} catch (err) {}
}, 3000);
}, 1000);
</script>
<style>

View File

@ -27,7 +27,7 @@ if (!function_exists('getSetting')) {
$site_logo = getSetting('site_logo', '');
$site_name = getSetting('site_name', 'Byro');
?>
<title><?= $site_name ?> | Professional Digital Asset Exchange</title>
<title><?= $site_name ?> | <?= __('site_title') ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<link rel="stylesheet" href="/assets/css/style.css?v=<?= time() ?>">

View File

@ -66,7 +66,7 @@ $translations = [
'advantage_3_desc' => '全天候多语言在线客服,随时解答您的任何疑问。',
'advantage_4_title' => '多样化产品',
'advantage_4_desc' => '涵盖现货、合约、秒合约、挖矿等多种投资工具。',
'about_content' => 'Byro 是一家全球领先的数字货币交易平台,成立于 2023 年,致力于为全球用户提供安全、专业、透明 of 数字资产金融服务。',
'about_content' => 'Byro 是一家全球领先的数字货币交易平台,成立于 2023 年,致力于为全球用户提供安全、专业、透明数字资产金融服务。',
'real_name' => '实名认证',
'verified' => '已认证',
'unverified' => '未认证',
@ -98,7 +98,7 @@ $translations = [
'start_mining' => '开始挖矿',
'why_mining' => '为什么选择 Byro 挖矿?',
'adv_hardware' => '先进硬件',
'adv_hardware_desc' => '我们使用最新的 ASIC 和 GPU 矿机,确保最高利润 and 稳定性。',
'adv_hardware_desc' => '我们使用最新的 ASIC 和 GPU 矿机,确保最高利润稳定性。',
'auto_compound' => '自动复利',
'auto_compound_desc' => '自动重新投资您的每日奖励,以实现长期收益最大化。',
'real_time_monitor' => '实时监控',
@ -277,6 +277,47 @@ $translations = [
'settlement_price' => '结算价格',
'purchase_amount' => '认购金额',
'recharge_amount' => '充值金额',
'site_title' => '专业数字资产交易平台',
'recharge_step1' => '选择充值方式(法币或加密货币)',
'recharge_step2' => '填写金额或复制充值地址',
'recharge_step3' => '完成支付后点击确认提交',
'recharge_step4' => '等待客服核实,资金通常在 2-5 分钟内到账',
'recharge_tip1' => '请勿向任何非官方提供的地址充值',
'recharge_tip2' => '充值前请仔细核对主网协议(如 TRC20/ERC20',
'recharge_tip3' => '请保管好您的支付凭证,以便在需要时提供给客服',
'recharge_tip4' => '平台绝不会要求您在非官方页面输入支付密码',
'withdraw_address_placeholder' => '请输入您的 USDT 地址',
'withdraw_amount_min' => '最小提现 10.00',
'withdraw_pwd_placeholder' => '默认密码 123456',
'withdraw_fee' => '手续费',
'withdraw_step1' => '选择提现方式(加密货币或法币)',
'withdraw_step2' => '填写提现地址/选择币种并输入金额',
'withdraw_step3' => '输入提现密码(默认 123456',
'withdraw_step4' => '确认后提交审核,预计 10-30 分钟内处理',
'withdraw_tip1' => '提现前请务必确认地址正确,转错将无法找回',
'withdraw_tip2' => '为了您的资金安全,大额提现可能需要人工电话核实',
'withdraw_tip3' => '请确保提现主网与接收端主网一致(如均为 TRC20',
'withdraw_tip4' => '严禁参与任何非法洗钱活动,平台将配合监管部门调查',
'approved' => '通过',
'rejected' => '拒绝',
'login_admin_error' => '管理员请通过后台页面登录',
'fill_full_info' => '请填写完整信息',
'verification_code' => '验证码',
'agree_tos_privacy' => '我已阅读并同意《服务协议》和《隐私政策》',
'register_now' => '立即注册',
'resend' => '重新发送',
'send_failed' => '发送失败',
'invalid_email' => '无效的邮箱地址',
'congrats_won' => '恭喜你获利',
'sorry_lost' => '很遗憾亏损',
'trade_won' => '交易获利',
'trade_lost' => '交易亏损',
'confirm' => '确 认',
'buy' => '买',
'sell' => '卖',
'approx' => '约等于',
'cookie_policy_title' => 'Cookie 政策',
'cookie_policy_content' => '<h3>1. 什么是 Cookie</h3><p>Cookie 是您访问网站时存储在您的计算机或移动设备上的小文本文件。它们广泛用于使网站运行或更高效地运行,并向网站所有者提供信息。</p><h3>2. 我们如何使用 Cookie</h3><p>我们使用 Cookie 来提升您的体验,记住您的偏好,并分析我们的流量。我们使用的 Cookie 包括:</p><ul><li><strong>必需 Cookie</strong> 网站正常运行所必需的。这些 Cookie 确保您可以安全地登录并使用平台的核心功能。</li><li><strong>功能性 Cookie</strong> 记住您的语言偏好、显示设置和登录状态,为您提供个性化的体验。</li><li><strong>分析与性能 Cookie</strong> 帮助我们了解用户如何与网站互动,发现并解决任何技术问题。</li><li><strong>安全 Cookie</strong> 用于辅助识别和防止潜在的安全风险,保护您的账户。</li></ul><h3>3. 第三方 Cookie</h3><p>除我们自己的 Cookie 外,我们还可能使用各种第三方 Cookie 来报告网站的使用统计数据、在网站上及通过网站提供广告等。</p><h3>4. 您的选择与控制</h3><p>您可以随时通过浏览器设置控制和/或删除 Cookie。您可以删除计算机上已有的所有 Cookie并且大多数浏览器可以设置为阻止放置它们。但请注意如果您禁用某些 Cookie平台的某些功能可能无法正常运行。</p><h3>5. 隐私保障</h3><p>我们致力于保护您的隐私。Cookie 不会用于收集您的个人敏感信息,除非您明确提供。有关我们如何处理您的数据的更多信息,请参阅我们的隐私政策。</p>',
],
'en' => [
'home' => 'Home',
@ -547,6 +588,47 @@ $translations = [
'settlement_price' => 'Settlement Price',
'purchase_amount' => 'Purchase Amount',
'recharge_amount' => 'Recharge Amount',
'site_title' => 'Professional Digital Asset Exchange',
'recharge_step1' => 'Select recharge method (fiat or crypto)',
'recharge_step2' => 'Fill in amount or copy deposit address',
'recharge_step3' => 'Submit after payment completion',
'recharge_step4' => 'Wait for verification (usually 2-5 mins)',
'recharge_tip1' => 'Do not deposit to any non-official addresses',
'recharge_tip2' => 'Check mainnet protocol carefully (TRC20/ERC20)',
'recharge_tip3' => 'Keep your payment voucher for support',
'recharge_tip4' => 'We never ask for payment password on unofficial pages',
'withdraw_address_placeholder' => 'Please enter your USDT address',
'withdraw_amount_min' => 'Min withdrawal 10.00',
'withdraw_pwd_placeholder' => 'Default password 123456',
'withdraw_fee' => 'Fee',
'withdraw_step1' => 'Select withdrawal method (crypto or fiat)',
'withdraw_step2' => 'Fill address and enter amount',
'withdraw_step3' => 'Enter withdrawal password (default 123456)',
'withdraw_step4' => 'Submit for review (usually 10-30 mins)',
'withdraw_tip1' => 'Ensure address is correct; transfers cannot be reversed',
'withdraw_tip2' => 'Large withdrawals may require phone verification',
'withdraw_tip3' => 'Ensure mainnet matches receiving end (e.g. TRC20)',
'withdraw_tip4' => 'Illegal money laundering activities are strictly prohibited',
'approved' => 'Approved',
'rejected' => 'Rejected',
'login_admin_error' => 'Administrators please log in via backend',
'fill_full_info' => 'Please fill in all information',
'verification_code' => 'Code',
'agree_tos_privacy' => 'I have read and agree to the Terms and Privacy Policy',
'register_now' => 'Register Now',
'resend' => 'Resend',
'send_failed' => 'Send failed',
'invalid_email' => 'Invalid email address',
'congrats_won' => 'Congratulations you won',
'sorry_lost' => 'Sorry you lost',
'trade_won' => 'Trade Won',
'trade_lost' => 'Trade Lost',
'confirm' => 'Confirm',
'buy' => 'Buy',
'sell' => 'Sell',
'approx' => '≈',
'cookie_policy_title' => 'Cookie Policy',
'cookie_policy_content' => '<h3>1. What are Cookies?</h3><p>Cookies are small text files stored on your computer or mobile device when you visit a website. They are widely used to make websites work, or work more efficiently, as well as to provide information to the owners of the site.</p><h3>2. How do we use Cookies?</h3><p>We use cookies to enhance your experience, remember your preferences, and analyze our traffic. The cookies we use include:</p><ul><li><strong>Essential Cookies:</strong> Necessary for the website to function properly.</li><li><strong>Functional Cookies:</strong> To remember your language preferences and login status.</li><li><strong>Analytical Cookies:</strong> To help us understand how users interact with the website.</li></ul><h3>3. Your Choices</h3><p>You can control and/or delete cookies as you wish through your browser settings. You can delete all cookies that are already on your computer and you can set most browsers to prevent them from being placed.</p>',
]
];

View File

@ -35,11 +35,19 @@ function renderTerminal($activeTab = 'spot') {
<link rel="stylesheet" href="/assets/css/terminal.css?v=<?= time() ?>">
<div class="terminal-sidebar-overlay" id="sidebar-overlay" onclick="toggleMobileSidebar()"></div>
<div class="terminal-container">
<!-- Mobile Top Switcher - Hidden on desktop to avoid duplicate fonts/text -->
<!-- Mobile Top Switcher - Redesigned as a module -->
<div class="mobile-type-switcher d-md-none">
<a href="/binary.php?symbol=<?= $currentSymbol ?>" class="<?= $activeTab === 'binary' ? 'active' : '' ?>"><?= __('sec_contract') ?></a>
<a href="/trade.php?symbol=<?= $currentSymbol ?>" class="<?= $activeTab === 'spot' ? 'active' : '' ?>"><?= __('spot') ?></a>
<a href="/contract.php?symbol=<?= $currentSymbol ?>" class="<?= $activeTab === 'contract' ? 'active' : '' ?>"><?= __('contract') ?></a>
<div class="switcher-module">
<a href="/binary.php?symbol=<?= $currentSymbol ?>" class="switcher-item <?= $activeTab === 'binary' ? 'active' : '' ?>">
<span><?= __('sec_contract') ?></span>
</a>
<a href="/trade.php?symbol=<?= $currentSymbol ?>" class="switcher-item <?= $activeTab === 'spot' ? 'active' : '' ?>">
<span><?= __('spot') ?></span>
</a>
<a href="/contract.php?symbol=<?= $currentSymbol ?>" class="switcher-item <?= $activeTab === 'contract' ? 'active' : '' ?>">
<span><?= __('contract') ?></span>
</a>
</div>
</div>
<div class="terminal-main">
<!-- Left Sidebar -->
@ -340,6 +348,7 @@ function renderTerminal($activeTab = 'spot') {
const amount = parseFloat(order.amount);
const profit = amount * order.profitRate / 100;
order.pnl = data.pnl;
// If won, total is principal + profit. If lost, total is 0.
order.total = data.result === 'won' ? (amount + profit).toFixed(2) : '0.00';
order.close_price = closePrice;
@ -347,10 +356,8 @@ function renderTerminal($activeTab = 'spot') {
historyData.open = historyData.open.filter(o => o.id !== order.id);
historyData.settlement.unshift(order);
// Refresh history tabs immediately
if (showHistoryTab.currentTab === 'open' || showHistoryTab.currentTab === 'settlement') {
showHistoryTab(showHistoryTab.currentTab);
}
// Automatically switch to settlement tab to show the result immediately in the list
showHistoryTab('settlement');
if (data.result === 'won') {
const balance = parseFloat(document.getElementById('user-usdt-balance').innerText.replace(',', ''));
@ -369,17 +376,19 @@ function renderTerminal($activeTab = 'spot') {
function showOrderResult(result, pnl, settlePrice, orderAmount) {
const popupOverlay = document.getElementById('order-popup-overlay');
const popup = popupOverlay.querySelector('.order-popup');
const resultContainer = document.getElementById('popup-result-content');
const countdownContainer = document.getElementById('popup-countdown-content');
// Clear current content but keep the container
popup.innerHTML = '';
popupOverlay.style.display = 'flex';
countdownContainer.style.display = 'none';
resultContainer.style.display = 'block';
const pnlAmount = parseFloat(Math.abs(pnl)).toFixed(2);
const isWon = result === 'won';
let message = isWon ?
('恭喜你获利' + ' ' + pnlAmount + ' USDT') :
('很遗憾亏损' + ' ' + pnlAmount + ' USDT');
('<?= __("congrats_won") ?>' + ' ' + pnlAmount + ' USDT') :
('<?= __("sorry_lost") ?>' + ' ' + pnlAmount + ' USDT');
const resultHtml = `
<div class="order-result-display animate__animated animate__zoomIn">
@ -391,33 +400,33 @@ function renderTerminal($activeTab = 'spot') {
</div>
<h3 class="result-title ${isWon ? 'text-success' : 'text-danger'} mb-2 fw-bold">
${isWon ? '交易获利' : '交易亏损'}
${isWon ? '<?= __("trade_won") ?>' : '<?= __("trade_lost") ?>'}
</h3>
<p class="result-message mb-4 fw-bold fs-5">
<p class="result-message mb-4 fw-bold fs-5 text-white">
${message}
</p>
<div class="result-card mb-4 bg-dark bg-opacity-50 p-3 rounded-3 border border-secondary">
<div class="result-card mb-4 bg-dark bg-opacity-50 p-3 rounded-3 border border-secondary text-start">
<div class="result-row d-flex justify-content-between mb-2">
<span class="text-muted">结算价格</span>
<span class="text-muted"><?= __("settlement_price") ?></span>
<span class="text-white fw-bold">${settlePrice.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}</span>
</div>
<div class="result-row d-flex justify-content-between mb-2">
<span class="text-muted">下单金额</span>
<span class="text-muted"><?= __("purchase_amount") ?></span>
<span class="text-white fw-bold">${parseFloat(orderAmount).toFixed(2)} USDT</span>
</div>
<div class="result-row total d-flex justify-content-between mt-2 pt-2 border-top border-secondary">
<span class="text-muted">交割返还</span>
<span class="text-muted"><?= __("total") ?></span>
<span class="fs-5 fw-bold ${isWon ? 'text-success' : 'text-danger'}">${isWon ? (parseFloat(pnl) + parseFloat(orderAmount)).toFixed(2) : '0.00'} USDT</span>
</div>
</div>
<button class="btn btn-primary w-100 py-2 fw-bold rounded-pill" onclick="hideOrderPopup()"> </button>
<button class="btn btn-primary w-100 py-2 fw-bold rounded-pill" onclick="hideOrderPopup()"><?= __("confirm") ?></button>
</div>
`;
popup.innerHTML = resultHtml;
resultContainer.innerHTML = resultHtml;
}
@ -453,16 +462,13 @@ function renderTerminal($activeTab = 'spot') {
}
function showOrderPopup(order) {
const popup = document.getElementById('order-popup-overlay');
const popupOverlay = document.getElementById('order-popup-overlay');
// Reset popup content
document.querySelector('.countdown-circle').style.display = 'block';
document.querySelector('.popup-details').style.display = 'block';
document.querySelector('.popup-footer').style.display = 'block';
const oldResult = document.querySelector('.order-result-display');
if (oldResult) oldResult.remove();
// Reset popup content to countdown view
document.getElementById('popup-countdown-content').style.display = 'block';
document.getElementById('popup-result-content').style.display = 'none';
const sideColor = order.side.includes('Up') || order.side.includes('涨') ? '#26a69a' : '#ef5350';
const sideColor = order.side.includes('Up') || order.side.includes('涨') || order.side.includes('<?= __("buy_up") ?>') ? '#26a69a' : '#ef5350';
document.getElementById('popup-price').innerText = order.price;
document.getElementById('popup-cycle').innerText = order.totalSeconds + '<?= __('unit_seconds') ?>';
@ -471,7 +477,7 @@ function renderTerminal($activeTab = 'spot') {
document.getElementById('popup-quantity').innerText = order.amount + ' USDT';
document.getElementById('popup-open-price').innerText = order.price;
popup.style.display = 'flex';
popupOverlay.style.display = 'flex';
updateOrderPopup(order);
}
@ -1000,7 +1006,7 @@ function renderTerminal($activeTab = 'spot') {
<div class="small opacity-75 text-muted">${total} USDT</div>`;
}
const isUp = row.side_type === 'up' || row.side.includes('Up') || row.side.includes('涨') || row.side === 'Buy' || row.side === 'Long';
const isUp = row.side_type === 'up' || row.side.includes('Up') || row.side.includes('涨') || row.side.includes('<?= __("buy_up") ?>') || row.side === 'Buy' || row.side === 'Long';
let operationHtml = `<button class="btn btn-sm btn-dark px-2 py-0" style="font-size: 10px;"><?= __('details') ?></button>`;
if (tab === 'open' && row.type === 'Contract') {
@ -1053,43 +1059,49 @@ function renderTerminal($activeTab = 'spot') {
<!-- Order Countdown Popup Modal -->
<div class="order-popup-overlay" id="order-popup-overlay">
<div class="order-popup">
<h5><?= __('order_in_progress') ?></h5>
<div class="order-popup position-relative">
<button class="btn-close btn-close-white position-absolute top-0 end-0 m-3" onclick="hideOrderPopup()" aria-label="Close" style="z-index: 10;"></button>
<div class="countdown-circle">
<svg width="200" height="200" viewBox="0 0 200 200">
<circle class="bg" cx="100" cy="100" r="90"></circle>
<circle class="progress" id="popup-progress" cx="100" cy="100" r="90"></circle>
</svg>
<div class="time-text" id="popup-time-text">60</div>
</div>
<div id="popup-countdown-content">
<h5><?= __('order_in_progress') ?></h5>
<div class="countdown-circle">
<svg width="200" height="200" viewBox="0 0 200 200">
<circle class="bg" cx="100" cy="100" r="90"></circle>
<circle class="progress" id="popup-progress" cx="100" cy="100" r="90"></circle>
</svg>
<div class="time-text" id="popup-time-text">60</div>
</div>
<div class="popup-details">
<div class="popup-row">
<span class="label"><?= __('current_price') ?></span>
<span class="value" id="popup-price">---</span>
<div class="popup-details">
<div class="popup-row">
<span class="label"><?= __('current_price') ?></span>
<span class="value" id="popup-price">---</span>
</div>
<div class="popup-row">
<span class="label"><?= __('cycle') ?></span>
<span class="value" id="popup-cycle">60<?= __('unit_seconds') ?></span>
</div>
<div class="popup-row">
<span class="label"><?= __('direction') ?></span>
<span class="value" id="popup-direction">---</span>
</div>
<div class="popup-row">
<span class="label"><?= __('quantity') ?></span>
<span class="value" id="popup-quantity">---</span>
</div>
<div class="popup-row">
<span class="label"><?= __('opening_price') ?></span>
<span class="value" id="popup-open-price">---</span>
</div>
</div>
<div class="popup-row">
<span class="label"><?= __('cycle') ?></span>
<span class="value" id="popup-cycle">60<?= __('unit_seconds') ?></span>
</div>
<div class="popup-row">
<span class="label"><?= __('direction') ?></span>
<span class="value" id="popup-direction">---</span>
</div>
<div class="popup-row">
<span class="label"><?= __('quantity') ?></span>
<span class="value" id="popup-quantity">---</span>
</div>
<div class="popup-row">
<span class="label"><?= __('opening_price') ?></span>
<span class="value" id="popup-open-price">---</span>
</div>
</div>
<div class="popup-footer">
<?= __('final_price_settlement') ?>
<div class="popup-footer">
<?= __('final_price_settlement') ?>
</div>
</div>
<div id="popup-result-content" style="display: none;"></div>
</div>
</div>
<!-- Error Modal Popup -->

View File

@ -89,6 +89,33 @@ require_once __DIR__ . '/includes/header.php';
.price-display {
color: #ffffff;
}
@media (max-width: 768px) {
main.container {
padding-top: 80px !important;
}
#heroCarousel, .carousel-content {
height: 350px !important;
min-height: 350px !important;
}
.carousel-item h1 {
font-size: 1.8rem !important;
}
.carousel-item p {
font-size: 1rem !important;
margin-bottom: 20px !important;
}
.carousel-item .btn {
padding: 10px 20px !important;
font-size: 14px !important;
}
.col-md-3 {
width: 100% !important;
}
.partner-card {
padding: 15px !important;
}
}
</style>
<!-- Popular Markets (3x4 Layout) -->
<section class="market-section mb-5">

View File

@ -228,12 +228,20 @@ $kycStatusColor = [
<table class="table table-dark table-hover mb-0 align-middle small">
<thead class="bg-black bg-opacity-20 text-white-50 border-secondary">
<tr>
<th class="ps-4 py-3 border-secondary"><?= __('type') ?></th>
<th class="py-3 border-secondary"><?= __('amount') ?></th>
<th class="py-3 border-secondary"><?= __('status') ?></th>
<th class="text-end pe-4 py-3 border-secondary"><?= __('time') ?></th>
<th class="ps-4 py-3 border-secondary" style="width: 25%;"><?= __('type') ?></th>
<th class="py-3 border-secondary" style="width: 30%;"><?= __('amount') ?></th>
<th class="py-3 border-secondary" style="width: 20%;"><?= __('status') ?></th>
<th class="text-end pe-4 py-3 border-secondary" style="width: 25%;"><?= __('time') ?></th>
</tr>
</thead>
</table>
</div>
<!-- Scrollable Body for Transactions - Limited to 4 rows (approx 210px) -->
<div class="transaction-list-container" style="height: 240px; overflow-y: auto; scrollbar-width: none; -ms-overflow-style: none;">
<style>
.transaction-list-container::-webkit-scrollbar { display: none; }
</style>
<table class="table table-dark table-hover mb-0 align-middle small">
<tbody class="border-0">
<?php if (empty($transactions)): ?>
<tr>
@ -247,31 +255,37 @@ $kycStatusColor = [
$typeColor = 'text-primary';
$typeName = __($t['type']);
if (strpos($t['type'], 'win') !== false || $t['type'] === 'deposit' || $t['type'] === 'binary_win') $typeColor = 'text-success';
elseif (strpos($t['type'], 'loss') !== false || $t['type'] === 'withdraw' || $t['type'] === 'binary_loss') $typeColor = 'text-danger';
if (strpos($t['type'], 'win') !== false || $t['type'] === 'deposit' || $t['type'] === 'binary_win' || $t['type'] === 'recharge') $typeColor = 'text-success';
elseif (strpos($t['type'], 'loss') !== false || $t['type'] === 'withdraw' || $t['type'] === 'withdrawal' || $t['type'] === 'binary_loss') $typeColor = 'text-danger';
elseif ($t['type'] === 'flash_exchange') $typeColor = 'text-info';
elseif ($t['type'] === 'contract_settle') $typeColor = 'text-info';
$prefix = '';
if ($t['type'] === 'binary_win' || $t['type'] === 'deposit' || $t['type'] === 'contract_settle') $prefix = '+';
if ($t['type'] === 'binary_loss' || $t['type'] === 'withdraw' || $t['type'] === 'contract_margin') $prefix = '-';
if ($t['type'] === 'binary_win' || $t['type'] === 'deposit' || $t['type'] === 'recharge' || $t['type'] === 'contract_settle') $prefix = '+';
if ($t['type'] === 'binary_loss' || $t['type'] === 'withdraw' || $t['type'] === 'withdrawal' || $t['type'] === 'contract_margin') $prefix = '-';
$statusText = __('pending') ?? '处理中';
$statusClass = 'bg-warning text-warning';
if ($t['status'] === 'completed' || $t['status'] === 'approved') {
$statusText = __('approved') ?? '通过';
$statusClass = 'bg-success text-success';
} elseif ($t['status'] === 'rejected') {
$statusText = __('rejected') ?? '拒绝';
$statusClass = 'bg-danger text-danger';
}
?>
<tr class="border-secondary">
<td class="ps-4 py-3">
<td class="ps-4 py-3" style="width: 25%;">
<span class="<?= $typeColor ?> fw-bold"><?= $typeName ?></span>
</td>
<td class="py-3">
<td class="py-3" style="width: 30%;">
<span class="text-white fw-bold"><?= $prefix . number_format($t['amount'], 4) ?></span>
<span class="text-white-50 small"><?= $t['symbol'] ?></span>
</td>
<td class="py-3">
<?php if ($t['status'] === 'completed'): ?>
<span class="badge bg-success bg-opacity-10 text-success border border-success border-opacity-25 px-2 py-1"><?= __('completed') ?></span>
<?php else: ?>
<span class="badge bg-warning bg-opacity-10 text-warning border border-warning border-opacity-25 px-2 py-1"><?= __('pending') ?></span>
<?php endif; ?>
<td class="py-3" style="width: 20%;">
<span class="badge bg-opacity-10 <?= $statusClass ?> border border-opacity-25 px-2 py-1"><?= $statusText ?></span>
</td>
<td class="text-end pe-4 py-3">
<td class="text-end pe-4 py-3" style="width: 25%;">
<span class="text-white-50 x-small"><?= date('Y-m-d H:i', strtotime($t['created_at'])) ?></span>
</td>
</tr>

View File

@ -151,38 +151,38 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
<div class="card-body p-4">
<h5 class="text-white fw-bold mb-3"><i class="bi bi-journal-text text-primary me-2"></i> <?= __('recharge_steps') ?? 'Recharge Steps' ?></h5>
<div class="text-white-50 small lh-lg">
<div class="d-flex gap-3 mb-2">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">1</span>
<span>选择充值方式(法币或加密货币)</span>
</div>
<div class="d-flex gap-3 mb-2">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">2</span>
<span>填写金额或复制充值地址</span>
</div>
<div class="d-flex gap-3 mb-2">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">3</span>
<span>完成支付后点击确认提交</span>
</div>
<div class="d-flex gap-3">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">4</span>
<span>等待客服核实资金通常在2-5分钟内到账</span>
<div class="d-flex gap-3 mb-2">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">1</span>
<span><?= __('recharge_step1') ?></span>
</div>
<div class="d-flex gap-3 mb-2">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">2</span>
<span><?= __('recharge_step2') ?></span>
</div>
<div class="d-flex gap-3 mb-2">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">3</span>
<span><?= __('recharge_step3') ?></span>
</div>
<div class="d-flex gap-3">
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">4</span>
<span><?= __('recharge_step4') ?></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card bg-surface border-secondary rounded-4 h-100">
<div class="card-body p-4">
<h5 class="text-white fw-bold mb-3"><i class="bi bi-shield-lock text-success me-2"></i> <?= __('security_tips') ?? 'Security Tips' ?></h5>
<div class="text-white-50 small lh-lg">
<ul class="ps-3 mb-0">
<li>请勿向任何非官方提供的地址充值</li>
<li>充值前请仔细核对主网协议(如 TRC20/ERC20</li>
<li>请保管好您的支付凭证,以便在需要时提供给客服</li>
<li>平台绝不会要求您在非官方页面输入支付密码</li>
</ul>
</div>
<div class="col-md-6">
<div class="card bg-surface border-secondary rounded-4 h-100">
<div class="card-body p-4">
<h5 class="text-white fw-bold mb-3"><i class="bi bi-shield-lock text-success me-2"></i> <?= __('security_tips') ?? 'Security Tips' ?></h5>
<div class="text-white-50 small lh-lg">
<ul class="ps-3 mb-0">
<li><?= __('recharge_tip1') ?></li>
<li><?= __('recharge_tip2') ?></li>
<li><?= __('recharge_tip3') ?></li>
<li><?= __('recharge_tip4') ?></li>
</ul>
</div>
</div>
</div>
</div>

View File

@ -68,7 +68,7 @@ $available = $bal['available'] ?? 0;
<div class="mb-4">
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('withdraw_address') ?></label>
<input type="text" class="form-control bg-dark border-secondary text-white py-3" id="withdrawAddress" placeholder="请输入您的 USDT 地址">
<input type="text" class="form-control bg-dark border-secondary text-white py-3" id="withdrawAddress" placeholder="<?= __('withdraw_address_placeholder') ?>">
</div>
<div class="mb-4">
@ -77,19 +77,19 @@ $available = $bal['available'] ?? 0;
<span class="small text-white-50"><?= __('balance') ?>: <span class="text-white"><?= number_format($available, 2) ?> USDT</span></span>
</div>
<div class="input-group">
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="withdrawAmount" placeholder="最小提现 10.00" oninput="calculateCryptoWithdraw()">
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="withdrawAmount" placeholder="<?= __('withdraw_amount_min') ?>" oninput="calculateCryptoWithdraw()">
<button type="button" class="input-group-text bg-dark border-secondary text-primary fw-bold" onclick="setMax('withdrawAmount', 'cryptoReceiveAmount')">ALL</button>
</div>
</div>
<div class="mb-4">
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('withdraw_password') ?? '提现密码' ?></label>
<input type="password" class="form-control bg-dark border-secondary text-white py-3" id="withdrawPassword" placeholder="默认密码 123456">
<input type="password" class="form-control bg-dark border-secondary text-white py-3" id="withdrawPassword" placeholder="<?= __('withdraw_pwd_placeholder') ?>">
</div>
<div class="mb-5 p-4 bg-warning bg-opacity-10 border border-warning border-opacity-20 rounded-4">
<div class="d-flex justify-content-between align-items-center mb-2">
<span class="text-white-50 small">手续费 (Fee)</span>
<span class="text-white-50 small"><?= __('withdraw_fee') ?> (Fee)</span>
<span class="text-white small">1.00 USDT</span>
</div>
<div class="d-flex justify-content-between align-items-center">
@ -131,14 +131,14 @@ $available = $bal['available'] ?? 0;
<span class="small text-white-50"><?= __('balance') ?>: <span class="text-white"><?= number_format($available, 2) ?> USDT</span></span>
</div>
<div class="input-group">
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="fiatWithdrawAmount" placeholder="最小提现 10.00" oninput="calculateFiatWithdraw()">
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="fiatWithdrawAmount" placeholder="<?= __('withdraw_amount_min') ?>" oninput="calculateFiatWithdraw()">
<button type="button" class="input-group-text bg-dark border-secondary text-primary fw-bold" onclick="setMax('fiatWithdrawAmount', 'fiatReceiveAmount')">ALL</button>
</div>
</div>
<div class="mb-4">
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('withdraw_password') ?? '提现密码' ?></label>
<input type="password" class="form-control bg-dark border-secondary text-white py-3" id="fiatWithdrawPassword" placeholder="默认密码 123456">
<input type="password" class="form-control bg-dark border-secondary text-white py-3" id="fiatWithdrawPassword" placeholder="<?= __('withdraw_pwd_placeholder') ?>">
</div>
<div class="mb-5 p-4 bg-primary bg-opacity-10 border border-primary border-opacity-20 rounded-4">
@ -170,19 +170,19 @@ $available = $bal['available'] ?? 0;
<div class="text-white-50 small lh-lg">
<div class="d-flex gap-3 mb-2">
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">1</span>
<span>选择提现方式(加密货币或法币)</span>
<span><?= __('withdraw_step1') ?></span>
</div>
<div class="d-flex gap-3 mb-2">
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">2</span>
<span>填写提现地址/选择币种并输入金额</span>
<span><?= __('withdraw_step2') ?></span>
</div>
<div class="d-flex gap-3 mb-2">
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">3</span>
<span>输入提现密码默认123456</span>
<span><?= __('withdraw_step3') ?></span>
</div>
<div class="d-flex gap-3">
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">4</span>
<span>确认后提交审核预计10-30分钟内处理</span>
<span><?= __('withdraw_step4') ?></span>
</div>
</div>
</div>
@ -194,10 +194,10 @@ $available = $bal['available'] ?? 0;
<h5 class="text-white fw-bold mb-3"><i class="bi bi-shield-lock text-danger me-2"></i> <?= __('security_tips') ?? '安全提示' ?></h5>
<div class="text-white-50 small lh-lg">
<ul class="ps-3 mb-0">
<li>提现前请务必确认地址正确,转错将无法找回</li>
<li>为了您的资金安全,大额提现可能需要人工电话核实</li>
<li>请确保提现主网与接收端主网一致(如均为 TRC20</li>
<li>严禁参与任何非法洗钱活动,平台将配合监管部门调查</li>
<li><?= __('withdraw_tip1') ?></li>
<li><?= __('withdraw_tip2') ?></li>
<li><?= __('withdraw_tip3') ?></li>
<li><?= __('withdraw_tip4') ?></li>
</ul>
</div>
</div>