以修复
This commit is contained in:
parent
238c9e0d22
commit
231218bd5e
254
admin/agents.php
Normal file
254
admin/agents.php
Normal file
@ -0,0 +1,254 @@
|
||||
<?php
|
||||
require_once '../db/config.php';
|
||||
session_start();
|
||||
$pdo = db();
|
||||
|
||||
// Handle Actions
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['action'])) {
|
||||
$action = $_POST['action'];
|
||||
|
||||
if ($action == 'add_agent') {
|
||||
$username = $_POST['username'];
|
||||
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
||||
$role = 'agent';
|
||||
$remark = $_POST['remark'] ?? '';
|
||||
$permissions = isset($_POST['perms']) ? json_encode($_POST['perms']) : '[]';
|
||||
|
||||
$stmt = $pdo->prepare("INSERT INTO admins (username, password, role, permissions, remark) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$username, $password, $role, $permissions, $remark]);
|
||||
} elseif ($action == 'update_agent') {
|
||||
$id = $_POST['id'];
|
||||
$username = $_POST['username'];
|
||||
$remark = $_POST['remark'] ?? '';
|
||||
$permissions = isset($_POST['perms']) ? json_encode($_POST['perms']) : '[]';
|
||||
|
||||
$sql = "UPDATE admins SET username = ?, permissions = ?, remark = ? WHERE id = ?";
|
||||
$params = [$username, $permissions, $remark, $id];
|
||||
|
||||
if (!empty($_POST['password'])) {
|
||||
$sql = "UPDATE admins SET username = ?, permissions = ?, remark = ?, password = ? WHERE id = ?";
|
||||
$params = [$username, $permissions, $remark, password_hash($_POST['password'], PASSWORD_DEFAULT), $id];
|
||||
}
|
||||
$pdo->prepare($sql)->execute($params);
|
||||
} elseif ($action == 'delete_agent') {
|
||||
$id = $_POST['id'];
|
||||
$pdo->prepare("DELETE FROM admins WHERE id = ? AND role = 'agent'")->execute([$id]);
|
||||
}
|
||||
header("Location: agents.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$agents = $pdo->query("SELECT * FROM admins WHERE role = 'agent' ORDER BY id DESC")->fetchAll();
|
||||
$unread_msgs = $pdo->query("SELECT COUNT(*) FROM messages WHERE sender = 'user' AND is_read = 0")->fetchColumn();
|
||||
$pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN ('matching', 'submitting')")->fetchColumn();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>代理管理 - NovaEx 管理后台</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
:root { --primary: #f0b90b; --bg: #ffffff; --text: #1e2329; --border: #eaecef; }
|
||||
body { background: #f4f6f9; color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; margin: 0; }
|
||||
.admin-layout { display: flex; min-height: 100vh; }
|
||||
.sidebar { width: 250px; background: #ffffff; border-right: 1px solid var(--border); padding: 1.5rem; }
|
||||
.main-content { flex: 1; padding: 2rem; background: #ffffff; }
|
||||
.menu-item { padding: 12px 15px; color: #474d57; text-decoration: none; display: flex; align-items: center; gap: 12px; border-radius: 8px; margin-bottom: 8px; transition: 0.2s; }
|
||||
.menu-item:hover, .menu-item.active { background: #f5f5f5; color: var(--primary); font-weight: bold; }
|
||||
.badge { background: #f6465d; color: white; border-radius: 10px; padding: 2px 8px; font-size: 0.7rem; margin-left: auto; }
|
||||
|
||||
.card { background: white; border-radius: 12px; border: 1px solid var(--border); padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); }
|
||||
.table { width: 100%; border-collapse: collapse; margin-top: 1.5rem; }
|
||||
.table th, .table td { padding: 15px; text-align: left; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
|
||||
.table th { background: #f9fafb; color: #707a8a; font-weight: 600; text-transform: uppercase; font-size: 0.75rem; }
|
||||
|
||||
.btn { padding: 8px 16px; border-radius: 6px; font-size: 0.85rem; border: none; cursor: pointer; font-weight: 500; transition: 0.2s; display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
|
||||
.btn-primary { background: var(--primary); color: black; }
|
||||
.btn-danger { background: #f6465d; color: white; }
|
||||
|
||||
.modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-content { background: white; width: 600px; padding: 30px; border-radius: 16px; box-shadow: 0 20px 40px rgba(0,0,0,0.2); max-height: 90vh; overflow-y: auto; }
|
||||
.form-group { margin-bottom: 20px; }
|
||||
.form-group label { display: block; margin-bottom: 8px; font-weight: 600; color: #474d57; }
|
||||
.form-group input, .form-group select, .form-group textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; font-size: 1rem; outline: none; box-sizing: border-box; }
|
||||
|
||||
.perms-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; border: 1px solid var(--border); padding: 15px; border-radius: 8px; }
|
||||
.perm-item { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="admin-layout">
|
||||
<div class="sidebar">
|
||||
<h2 style="color: var(--primary); margin-bottom: 2rem;">NovaEx Admin</h2>
|
||||
<a href="index.php" class="menu-item"><i class="fas fa-home"></i> 仪表盘</a>
|
||||
<a href="users.php" class="menu-item"><i class="fas fa-users"></i> 用户管理</a>
|
||||
<a href="agents.php" class="menu-item active"><i class="fas fa-user-shield"></i> 代理管理</a>
|
||||
<a href="kyc.php" class="menu-item"><i class="fas fa-id-card"></i> KYC 审核</a>
|
||||
<a href="chat.php" class="menu-item">
|
||||
<i class="fas fa-comments"></i> 客服管理
|
||||
<?php if($unread_msgs > 0 || $pending_orders > 0): ?><span class="badge"><?php echo ($unread_msgs + $pending_orders); ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="options_orders.php" class="menu-item"><i class="fas fa-clock"></i> 秒合约</a>
|
||||
<a href="spot_orders.php" class="menu-item"><i class="fas fa-exchange-alt"></i> 现货交易</a>
|
||||
<a href="futures_orders.php" class="menu-item"><i class="fas fa-file-contract"></i> 合约交易</a>
|
||||
<a href="orders.php" class="menu-item"><i class="fas fa-wallet"></i> 充值记录</a>
|
||||
<a href="settings.php" class="menu-item"><i class="fas fa-cog"></i> 系统设置</a>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px;">
|
||||
<h1>代理管理</h1>
|
||||
<button class="btn btn-primary" onclick="showModal('addAgentModal')"><i class="fas fa-plus"></i> 添加子管理员/代理</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID / 账号</th>
|
||||
<th>角色</th>
|
||||
<th>备注</th>
|
||||
<th>权限范围</th>
|
||||
<th>创建时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($agents as $agent): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold;"><?php echo $agent['id']; ?></div>
|
||||
<div style="font-size: 0.9rem; color: #474d57;"><?php echo htmlspecialchars($agent['username']); ?></div>
|
||||
</td>
|
||||
<td><span style="background: #eef2f7; padding: 4px 8px; border-radius: 4px; font-size: 0.8rem;">分管理代理</span></td>
|
||||
<td style="color: #707a8a; font-size: 0.85rem;"><?php echo htmlspecialchars($agent['remark'] ?: '-'); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$perms = json_decode($agent['permissions'] ?: '[]', true);
|
||||
if(empty($perms)) echo '<span style="color: #ccc;">无权限</span>';
|
||||
else echo '<span style="font-size: 0.75rem; color: #00c087;">' . count($perms) . ' 项权限</span>';
|
||||
?>
|
||||
</td>
|
||||
<td style="font-size: 0.8rem; color: #848e9c;"><?php echo $agent['created_at']; ?></td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<button class="btn btn-primary btn-sm" onclick='editAgent(<?php echo json_encode($agent); ?>)'><i class="fas fa-edit"></i></button>
|
||||
<form method="POST" style="display: inline;" onsubmit="return confirm('确定要删除此代理吗?')">
|
||||
<input type="hidden" name="id" value="<?php echo $agent['id']; ?>">
|
||||
<input type="hidden" name="action" value="delete_agent">
|
||||
<button type="submit" class="btn btn-danger btn-sm"><i class="fas fa-trash"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Agent Modal -->
|
||||
<div id="addAgentModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header" style="display: flex; justify-content: space-between; margin-bottom: 20px;">
|
||||
<h3>添加代理管理员</h3>
|
||||
<i class="fas fa-times" onclick="hideModal('addAgentModal')" style="cursor: pointer;"></i>
|
||||
</div>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="add_agent">
|
||||
<div class="form-group">
|
||||
<label>登录账号</label>
|
||||
<input type="text" name="username" required placeholder="输入代理登录用户名">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>登录密码</label>
|
||||
<input type="password" name="password" required placeholder="输入登录密码">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>代理备注</label>
|
||||
<textarea name="remark" rows="2" placeholder="备注该代理的线下明确信息..."></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>设置权限</label>
|
||||
<div class="perms-grid">
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="users"> 用户管理</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="kyc"> KYC 审核</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="chat"> 客服管理</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="options"> 秒合约订单</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="spot"> 现货订单</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="futures"> 合约订单</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="orders"> 充值记录</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: right; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('addAgentModal')">取消</button>
|
||||
<button type="submit" class="btn btn-primary">确认添加</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Agent Modal -->
|
||||
<div id="editAgentModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header" style="display: flex; justify-content: space-between; margin-bottom: 20px;">
|
||||
<h3>编辑代理权限</h3>
|
||||
<i class="fas fa-times" onclick="hideModal('editAgentModal')" style="cursor: pointer;"></i>
|
||||
</div>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="update_agent">
|
||||
<input type="hidden" name="id" id="edit_agent_id">
|
||||
<div class="form-group">
|
||||
<label>登录账号</label>
|
||||
<input type="text" name="username" id="edit_agent_username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>修改密码 (不填则不修改)</label>
|
||||
<input type="password" name="password" placeholder="留空保持原密码">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>代理备注</label>
|
||||
<textarea name="remark" id="edit_agent_remark" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>权限设置</label>
|
||||
<div class="perms-grid" id="edit_perms_grid">
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="users"> 用户管理</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="kyc"> KYC 审核</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="chat"> 客服管理</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="options"> 秒合约订单</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="spot"> 现货订单</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="futures"> 合约订单</div>
|
||||
<div class="perm-item"><input type="checkbox" name="perms[]" value="orders"> 充值记录</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: right; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('editAgentModal')">取消</button>
|
||||
<button type="submit" class="btn btn-primary">保存修改</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showModal(id) { document.getElementById(id).style.display = 'flex'; }
|
||||
function hideModal(id) { document.getElementById(id).style.display = 'none'; }
|
||||
|
||||
function editAgent(agent) {
|
||||
document.getElementById('edit_agent_id').value = agent.id;
|
||||
document.getElementById('edit_agent_username').value = agent.username;
|
||||
document.getElementById('edit_agent_remark').value = agent.remark || '';
|
||||
|
||||
const perms = JSON.parse(agent.permissions || '[]');
|
||||
const checkboxes = document.querySelectorAll('#edit_perms_grid input[type="checkbox"]');
|
||||
checkboxes.forEach(cb => {
|
||||
cb.checked = perms.includes(cb.value);
|
||||
});
|
||||
|
||||
showModal('editAgentModal');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -13,83 +13,83 @@ $unread_msgs = $db->query("SELECT COUNT(*) FROM messages WHERE sender = 'user' A
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>管理后台 - NovaEx</title>
|
||||
<link rel="stylesheet" href="../assets/css/custom.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
:root { --primary: #f0b90b; --bg: #ffffff; --text: #1e2329; --border: #eaecef; }
|
||||
body { background: #f4f6f9; color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; margin: 0; }
|
||||
.admin-layout { display: flex; min-height: 100vh; }
|
||||
.sidebar { width: 250px; background: #FFFFFF; border-right: 1px solid #EAECEF; padding: 1rem; }
|
||||
.main-content { flex: 1; padding: 2rem; background: #FFFFFF; }
|
||||
.menu-item { padding: 12px; color: #474D57; text-decoration: none; display: flex; align-items: center; gap: 10px; border-radius: 4px; margin-bottom: 5px; }
|
||||
.menu-item:hover, .menu-item.active { background: #F5F5F5; color: #F0B90B; }
|
||||
.badge { background: #F6465D; color: white; border-radius: 10px; padding: 2px 8px; font-size: 0.7rem; margin-left: auto; }
|
||||
.stat-card { background: #F9FAFB; padding: 20px; border-radius: 8px; border: 1px solid #EAECEF; }
|
||||
.sidebar { width: 250px; background: #ffffff; border-right: 1px solid var(--border); padding: 1.5rem; }
|
||||
.main-content { flex: 1; padding: 2rem; background: #ffffff; }
|
||||
.menu-item { padding: 12px 15px; color: #474d57; text-decoration: none; display: flex; align-items: center; gap: 12px; border-radius: 8px; margin-bottom: 8px; transition: 0.2s; }
|
||||
.menu-item:hover, .menu-item.active { background: #f5f5f5; color: var(--primary); font-weight: bold; }
|
||||
.badge { background: #f6465d; color: white; border-radius: 10px; padding: 2px 8px; font-size: 0.7rem; margin-left: auto; }
|
||||
.stat-card { background: white; padding: 25px; border-radius: 12px; border: 1px solid var(--border); box-shadow: 0 2px 10px rgba(0,0,0,0.03); }
|
||||
.stat-label { color: #707a8a; font-size: 0.85rem; margin-bottom: 10px; font-weight: 600; text-transform: uppercase; }
|
||||
.stat-value { font-size: 2.2rem; font-weight: 800; color: #1e2329; }
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: #FFFFFF; color: #1E2329;">
|
||||
<body>
|
||||
<div class="admin-layout">
|
||||
<div class="sidebar">
|
||||
<h3 style="color: #1E2329; margin-bottom: 2rem;">NovaEx 管理员</h3>
|
||||
<a href="index.php" class="menu-item active"><i class="fas fa-chart-pie"></i> 仪表盘</a>
|
||||
<h2 style="color: var(--primary); margin-bottom: 2rem;">NovaEx Admin</h2>
|
||||
<a href="index.php" class="menu-item active"><i class="fas fa-home"></i> 仪表盘</a>
|
||||
<a href="users.php" class="menu-item"><i class="fas fa-users"></i> 用户管理</a>
|
||||
<a href="kyc.php" class="menu-item">
|
||||
<i class="fas fa-id-card"></i> KYC 审核
|
||||
<a href="agents.php" class="menu-item"><i class="fas fa-user-shield"></i> 代理管理</a>
|
||||
<a href="kyc.php" class="menu-item"><i class="fas fa-id-card"></i> KYC 审核
|
||||
<?php if($pending_kyc > 0): ?><span class="badge"><?php echo $pending_kyc; ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="chat.php" class="menu-item">
|
||||
<i class="fas fa-headset"></i> 客服管理
|
||||
<a href="chat.php" class="menu-item"><i class="fas fa-comments"></i> 客服管理
|
||||
<?php if($unread_msgs > 0 || $pending_orders > 0): ?><span class="badge"><?php echo ($unread_msgs + $pending_orders); ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="options_orders.php" class="menu-item"><i class="fas fa-clock"></i> 秒合约</a>
|
||||
<a href="spot_orders.php" class="menu-item"><i class="fas fa-exchange-alt"></i> 现货交易</a>
|
||||
<a href="futures_orders.php" class="menu-item"><i class="fas fa-file-contract"></i> 合约交易</a>
|
||||
<a href="orders.php" class="menu-item">
|
||||
<i class="fas fa-wallet"></i> 充值记录
|
||||
</a>
|
||||
<a href="orders.php" class="menu-item"><i class="fas fa-wallet"></i> 充值记录</a>
|
||||
<a href="settings.php" class="menu-item"><i class="fas fa-cog"></i> 系统设置</a>
|
||||
<a href="../index.php" class="menu-item" style="margin-top: 2rem; color: #F0B90B;"><i class="fas fa-external-link-alt"></i> 查看前端</a>
|
||||
<a href="../index.php" class="menu-item" style="margin-top: 2rem; color: #f0b90b;"><i class="fas fa-external-link-alt"></i> 前端首页</a>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<h2 style="color: #1E2329; margin-bottom: 2rem;">系统概览</h2>
|
||||
<div style="grid-template-columns: repeat(4, 1fr); display: grid; gap: 1.5rem;">
|
||||
<h1 style="margin-bottom: 2rem;">系统概览</h1>
|
||||
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem;">
|
||||
<div class="stat-card">
|
||||
<div style="color: #707A8A; font-size: 0.9rem;">总注册人数</div>
|
||||
<div style="font-size: 2rem; color: #1E2329; margin-top: 10px;"><?php echo $total_users; ?></div>
|
||||
<div class="stat-label">总注册用户</div>
|
||||
<div class="stat-value"><?php echo $total_users; ?></div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div style="color: #707A8A; font-size: 0.9rem;">待处理 KYC</div>
|
||||
<div style="font-size: 2rem; color: #F0B90B; margin-top: 10px;"><?php echo $pending_kyc; ?></div>
|
||||
<div class="stat-label">待审核 KYC</div>
|
||||
<div class="stat-value" style="color: #f0b90b;"><?php echo $pending_kyc; ?></div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div style="color: #707A8A; font-size: 0.9rem;">待匹配/审核充值</div>
|
||||
<div style="font-size: 2rem; color: #F0B90B; margin-top: 10px;"><?php echo $pending_orders; ?></div>
|
||||
<div class="stat-label">待匹配充值</div>
|
||||
<div class="stat-value" style="color: #f6465d;"><?php echo $pending_orders; ?></div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div style="color: #707A8A; font-size: 0.9rem;">未读消息</div>
|
||||
<div style="font-size: 2rem; color: #00C087; margin-top: 10px;"><?php echo $unread_msgs; ?></div>
|
||||
<div class="stat-label">待回复消息</div>
|
||||
<div class="stat-value" style="color: #00c087;"><?php echo $unread_msgs; ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 3rem; background: #F9FAFB; padding: 25px; border-radius: 8px; border: 1px solid #EAECEF;">
|
||||
<h3 style="color: #1E2329; margin-bottom: 20px;">控制中心</h3>
|
||||
<div style="margin-top: 3rem; background: #f9fafb; padding: 30px; border-radius: 16px; border: 1px solid var(--border);">
|
||||
<h2 style="margin-bottom: 20px;">控制中心</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;">
|
||||
<div style="border: 1px solid #EAECEF; padding: 20px; border-radius: 6px; background: white;">
|
||||
<h4 style="color: #474D57;">客服与充值管理</h4>
|
||||
<p style="color: #707A8A; font-size: 0.8rem;">与用户对话并处理实时的充值匹配请求。</p>
|
||||
<a href="chat.php" class="btn-primary" style="display: inline-block; margin-top: 15px; font-size: 0.8rem; padding: 8px 15px;">进入工作台</a>
|
||||
<div style="background: white; padding: 25px; border-radius: 12px; border: 1px solid var(--border);">
|
||||
<h3>充值与客服</h3>
|
||||
<p style="color: #707a8a; font-size: 0.9rem;">实时处理充值申请并与用户在线沟通。</p>
|
||||
<a href="chat.php" style="background: var(--primary); color: black; padding: 10px 20px; border-radius: 8px; text-decoration: none; display: inline-block; margin-top: 15px; font-weight: bold;">进入客服中心</a>
|
||||
</div>
|
||||
<div style="border: 1px solid #EAECEF; padding: 20px; border-radius: 6px; background: white;">
|
||||
<h4 style="color: #474D57;">交易管理</h4>
|
||||
<p style="color: #707A8A; font-size: 0.8rem;">审核并处理现货及合约交易订单。</p>
|
||||
<div style="display:flex; gap: 10px; margin-top: 15px;">
|
||||
<a href="options_orders.php" class="btn-primary" style="font-size: 0.75rem; padding: 5px 10px; background: #6c757d;">秒合约</a>
|
||||
<a href="spot_orders.php" class="btn-primary" style="font-size: 0.75rem; padding: 5px 10px; background: #377aff;">现货</a>
|
||||
<a href="futures_orders.php" class="btn-primary" style="font-size: 0.75rem; padding: 5px 10px; background: #f0b90b; color: white;">合约</a>
|
||||
<div style="background: white; padding: 25px; border-radius: 12px; border: 1px solid var(--border);">
|
||||
<h3>交易订单</h3>
|
||||
<p style="color: #707a8a; font-size: 0.9rem;">监控秒合约、现货及合约交易流水。</p>
|
||||
<div style="margin-top: 15px; display: flex; gap: 10px;">
|
||||
<a href="options_orders.php" style="background: #f4f6f9; color: #474d57; padding: 8px 15px; border-radius: 6px; text-decoration: none; font-size: 0.85rem;">秒合约</a>
|
||||
<a href="futures_orders.php" style="background: #f4f6f9; color: #474d57; padding: 8px 15px; border-radius: 6px; text-decoration: none; font-size: 0.85rem;">合约交易</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="border: 1px solid #EAECEF; padding: 20px; border-radius: 6px; background: white;">
|
||||
<h4 style="color: #474D57;">价格控制</h4>
|
||||
<p style="color: #707A8A; font-size: 0.8rem;">手动覆盖特定交易对的实时价格及插针控制。</p>
|
||||
<a href="settings.php" class="btn-primary" style="display: inline-block; margin-top: 15px; font-size: 0.8rem; padding: 8px 15px;">立即配置</a>
|
||||
<div style="background: white; padding: 25px; border-radius: 12px; border: 1px solid var(--border);">
|
||||
<h3>全局设置</h3>
|
||||
<p style="color: #707a8a; font-size: 0.9rem;">修改系统参数、胜率及站点 LOGO。</p>
|
||||
<a href="settings.php" style="color: var(--primary); text-decoration: none; display: block; margin-top: 15px; font-weight: bold;">立即配置 <i class="fas fa-arrow-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -3,38 +3,54 @@ require_once '../db/config.php';
|
||||
session_start();
|
||||
$pdo = db();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['action'])) {
|
||||
$id = $_POST['id'];
|
||||
$control = $_POST['control']; // 'none', 'win', 'loss'
|
||||
$stmt = $pdo->prepare("UPDATE option_orders SET control = ? WHERE id = ? AND status = 'pending'");
|
||||
$stmt->execute([$control, $id]);
|
||||
header("Location: options_orders.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$orders = $pdo->query("SELECT o.*, u.username, u.win_loss_control as user_control FROM option_orders o JOIN users u ON o.user_id = u.id ORDER BY o.id DESC")->fetchAll();
|
||||
$unread_msgs = $pdo->query("SELECT COUNT(*) FROM messages WHERE sender = 'user' AND is_read = 0")->fetchColumn();
|
||||
$pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN ('matching', 'submitting')")->fetchColumn();
|
||||
|
||||
$orders = $pdo->query("SELECT o.*, u.username FROM option_orders o JOIN users u ON o.user_id = u.id ORDER BY o.created_at DESC")->fetchAll();
|
||||
$pending_kyc = $pdo->query("SELECT COUNT(*) FROM users WHERE kyc_status = 1")->fetchColumn();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>秒合约详情 - NovaEx 管理后台</title>
|
||||
<link rel="stylesheet" href="../assets/css/custom.css">
|
||||
<title>秒合约订单 - NovaEx 管理后台</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
:root { --primary: #f0b90b; --bg: #ffffff; --text: #1e2329; --border: #eaecef; }
|
||||
body { background: #f4f6f9; color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; margin: 0; }
|
||||
.admin-layout { display: flex; min-height: 100vh; }
|
||||
.sidebar { width: 250px; background: #FFFFFF; border-right: 1px solid #EAECEF; padding: 1rem; }
|
||||
.main-content { flex: 1; padding: 2rem; background: #FFFFFF; color: #1E2329; }
|
||||
.menu-item { padding: 12px; color: #474D57; text-decoration: none; display: flex; align-items: center; gap: 10px; border-radius: 4px; margin-bottom: 5px; }
|
||||
.menu-item:hover, .menu-item.active { background: #F5F5F5; color: #F0B90B; }
|
||||
.badge { background: #F6465D; color: white; border-radius: 10px; padding: 2px 8px; font-size: 0.7rem; margin-left: auto; }
|
||||
.table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
|
||||
.table th, .table td { padding: 12px; text-align: left; border-bottom: 1px solid #EAECEF; font-size: 0.85rem; color: #1E2329; }
|
||||
.sidebar { width: 250px; background: #ffffff; border-right: 1px solid var(--border); padding: 1.5rem; }
|
||||
.main-content { flex: 1; padding: 2rem; background: #ffffff; }
|
||||
.menu-item { padding: 12px 15px; color: #474d57; text-decoration: none; display: flex; align-items: center; gap: 12px; border-radius: 8px; margin-bottom: 8px; transition: 0.2s; }
|
||||
.menu-item:hover, .menu-item.active { background: #f5f5f5; color: var(--primary); font-weight: bold; }
|
||||
.badge { background: #f6465d; color: white; border-radius: 10px; padding: 2px 8px; font-size: 0.7rem; margin-left: auto; }
|
||||
.card { background: white; border-radius: 12px; border: 1px solid var(--border); padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); }
|
||||
.table { width: 100%; border-collapse: collapse; margin-top: 1.5rem; font-size: 0.85rem; }
|
||||
.table th, .table td { padding: 12px; text-align: left; border-bottom: 1px solid var(--border); }
|
||||
.table th { background: #f9fafb; color: #707a8a; font-weight: 600; text-transform: uppercase; }
|
||||
.btn-sm { padding: 5px 10px; font-size: 0.75rem; border-radius: 4px; border: 1px solid transparent; cursor: pointer; }
|
||||
.control-active { border: 2px solid #000 !important; font-weight: bold; }
|
||||
</style>
|
||||
</head>
|
||||
<body style="background: white;">
|
||||
<body>
|
||||
<div class="admin-layout">
|
||||
<div class="sidebar">
|
||||
<h3 style="color: #1E2329; margin-bottom: 2rem;">NovaEx 管理员</h3>
|
||||
<a href="index.php" class="menu-item"><i class="fas fa-chart-pie"></i> 仪表盘</a>
|
||||
<h2 style="color: var(--primary); margin-bottom: 2rem;">NovaEx Admin</h2>
|
||||
<a href="index.php" class="menu-item"><i class="fas fa-home"></i> 仪表盘</a>
|
||||
<a href="users.php" class="menu-item"><i class="fas fa-users"></i> 用户管理</a>
|
||||
<a href="kyc.php" class="menu-item"><i class="fas fa-id-card"></i> KYC 审核</a>
|
||||
<a href="chat.php" class="menu-item">
|
||||
<i class="fas fa-headset"></i> 客服管理
|
||||
<a href="agents.php" class="menu-item"><i class="fas fa-user-shield"></i> 代理管理</a>
|
||||
<a href="kyc.php" class="menu-item"><i class="fas fa-id-card"></i> KYC 审核
|
||||
<?php if($pending_kyc > 0): ?><span class="badge"><?php echo $pending_kyc; ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="chat.php" class="menu-item"><i class="fas fa-comments"></i> 客服管理
|
||||
<?php if($unread_msgs > 0 || $pending_orders > 0): ?><span class="badge"><?php echo ($unread_msgs + $pending_orders); ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="options_orders.php" class="menu-item active"><i class="fas fa-clock"></i> 秒合约</a>
|
||||
@ -43,50 +59,76 @@ $orders = $pdo->query("SELECT o.*, u.username FROM option_orders o JOIN users u
|
||||
<a href="orders.php" class="menu-item"><i class="fas fa-wallet"></i> 充值记录</a>
|
||||
<a href="settings.php" class="menu-item"><i class="fas fa-cog"></i> 系统设置</a>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<h2>秒合约交易记录</h2>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>用户</th>
|
||||
<th>币对</th>
|
||||
<th>方向</th>
|
||||
<th>金额</th>
|
||||
<th>时长</th>
|
||||
<th>盈利率</th>
|
||||
<th>买入价</th>
|
||||
<th>结算价</th>
|
||||
<th>盈亏</th>
|
||||
<th>状态</th>
|
||||
<th>下单时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($orders as $o): ?>
|
||||
<tr>
|
||||
<td><?php echo $o['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($o['username']); ?></td>
|
||||
<td><?php echo $o['symbol']; ?></td>
|
||||
<td style="color: <?php echo $o['direction'] == 'up' ? '#00c087' : '#f6465d'; ?>">
|
||||
<?php echo $o['direction'] == 'up' ? '买涨 ↑' : '买跌 ↓'; ?>
|
||||
</td>
|
||||
<td><b><?php echo number_format($o['amount'], 2); ?></b></td>
|
||||
<td><?php echo $o['duration']; ?>s</td>
|
||||
<td><?php echo $o['profit_rate'] * 100; ?>%</td>
|
||||
<td><?php echo number_format($o['opening_price'], 4); ?></td>
|
||||
<td><?php echo $o['closing_price'] ? number_format($o['closing_price'], 4) : '--'; ?></td>
|
||||
<td style="color: <?php echo $o['result'] == 'win' ? '#00c087' : ($o['result'] == 'loss' ? '#f6465d' : 'inherit'); ?>">
|
||||
<?php echo $o['result'] == 'none' ? '--' : number_format($o['profit'], 2); ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $o['status'] == 'pending' ? '<span style="color: #f0b90b;">进行中</span>' : '<span style="color: #848e9c;">已完成</span>'; ?>
|
||||
</td>
|
||||
<td><?php echo $o['created_at']; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<h1>秒合约订单管理</h1>
|
||||
<div class="card" style="margin-top: 20px;">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID / 用户</th>
|
||||
<th>交易对</th>
|
||||
<th>方向</th>
|
||||
<th>金额</th>
|
||||
<th>周期</th>
|
||||
<th>开仓价</th>
|
||||
<th>状态</th>
|
||||
<th>当前控制</th>
|
||||
<th>时间</th>
|
||||
<th>输赢干预</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($orders as $o): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight: bold;"><?php echo $o['id']; ?></div>
|
||||
<div style="font-size: 0.75rem; color: #707a8a;"><?php echo htmlspecialchars($o['username']); ?></div>
|
||||
</td>
|
||||
<td><?php echo $o['symbol']; ?></td>
|
||||
<td><span style="color: <?php echo $o['direction'] == 'up' ? '#00c087' : '#f6465d'; ?>; font-weight: bold;"><?php echo $o['direction'] == 'up' ? '买涨 ↑' : '买跌 ↓'; ?></span></td>
|
||||
<td style="font-weight: bold;"><?php echo number_format($o['amount'], 2); ?></td>
|
||||
<td><?php echo $o['duration']; ?>s</td>
|
||||
<td><?php echo number_format($o['opening_price'], 2); ?></td>
|
||||
<td>
|
||||
<span style="background: #eef2f7; padding: 3px 8px; border-radius: 4px; font-size: 0.75rem;">
|
||||
<?php echo $o['status'] == 'pending' ? '进行中' : '已结算'; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$ctrl = $o['control'];
|
||||
if ($o['status'] == 'pending') {
|
||||
if ($ctrl != 'none') {
|
||||
echo "<span style='color: ".($ctrl == 'win' ? '#00c087' : '#f6465d')."; font-weight: bold;'>单控: ".($ctrl == 'win' ? '赢' : '亏')."</span>";
|
||||
} else {
|
||||
$uc = $o['user_control'];
|
||||
echo "<span style='color: #848e9c;'>".($uc == 'none' ? '默认' : ($uc == 'win' ? '全控赢' : '全控亏'))."</span>";
|
||||
}
|
||||
} else {
|
||||
echo "<span style='color: ".($o['result'] == 'win' ? '#00c087' : '#f6465d')."; font-weight: bold;'>".($o['result'] == 'win' ? '盈利' : '亏损')."</span>";
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td style="font-size: 0.75rem; color: #848e9c;"><?php echo $o['created_at']; ?></td>
|
||||
<td>
|
||||
<?php if($o['status'] == 'pending'): ?>
|
||||
<form method="POST" style="display: flex; gap: 5px;">
|
||||
<input type="hidden" name="id" value="<?php echo $o['id']; ?>">
|
||||
<input type="hidden" name="action" value="control">
|
||||
<button type="submit" name="control" value="win" class="btn-sm <?php echo $ctrl == 'win' ? 'control-active' : ''; ?>" style="background: #00c087; color: white;">控赢</button>
|
||||
<button type="submit" name="control" value="loss" class="btn-sm <?php echo $ctrl == 'loss' ? 'control-active' : ''; ?>" style="background: #f6465d; color: white;">控亏</button>
|
||||
<button type="submit" name="control" value="none" class="btn-sm <?php echo $ctrl == 'none' ? 'control-active' : ''; ?>" style="background: #eee; color: #333;">取消</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<span style="color: #ccc;">已结单</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@ -3,14 +3,42 @@ require_once '../db/config.php';
|
||||
session_start();
|
||||
$db = db();
|
||||
|
||||
// Basic security check (could be improved with a proper login session for admins)
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
// For now, if not logged in at all, redirect to main login
|
||||
// In a real scenario, we'd have a separate admin login
|
||||
}
|
||||
|
||||
$message = "";
|
||||
$error = "";
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['settings'])) {
|
||||
foreach ($_POST['settings'] as $name => $value) {
|
||||
$stmt = $db->prepare("INSERT INTO settings (name, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value = ?");
|
||||
$stmt->execute([$name, $value, $value]);
|
||||
}
|
||||
$message = "系统设置已成功更新。";
|
||||
}
|
||||
|
||||
if (isset($_FILES['logo']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) {
|
||||
$ext = pathinfo($_FILES['logo']['name'], PATHINFO_EXTENSION);
|
||||
$filename = 'logo_' . time() . '.' . $ext;
|
||||
$target = '../assets/images/' . $filename;
|
||||
|
||||
if (!is_dir('../assets/images')) {
|
||||
mkdir('../assets/images', 0775, true);
|
||||
}
|
||||
|
||||
if (move_uploaded_file($_FILES['logo']['tmp_name'], $target)) {
|
||||
$logo_url = 'assets/images/' . $filename;
|
||||
$stmt = $db->prepare("INSERT INTO settings (name, value) VALUES ('site_logo', ?) ON DUPLICATE KEY UPDATE value = ?");
|
||||
$stmt->execute([$logo_url, $logo_url]);
|
||||
$message = "LOGO 已成功上传。";
|
||||
} else {
|
||||
$error = "LOGO 上传失败。";
|
||||
}
|
||||
}
|
||||
$message = "系统设置已成功更新。";
|
||||
}
|
||||
|
||||
$settings_res = $db->query("SELECT * FROM settings")->fetchAll();
|
||||
@ -24,90 +52,121 @@ $pending_orders = $db->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN (
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>系统设置 - NovaEx 管理后台</title>
|
||||
<link rel="stylesheet" href="../assets/css/custom.css">
|
||||
<title>系统设置 - 管理后台</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
:root { --primary: #f0b90b; --bg: #ffffff; --text: #1e2329; --border: #eaecef; --card-bg: #f9fafb; }
|
||||
body { background: #f4f6f9; color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; margin: 0; }
|
||||
.admin-layout { display: flex; min-height: 100vh; }
|
||||
.sidebar { width: 250px; background: #1E2329; border-right: 1px solid #2B3139; padding: 1rem; }
|
||||
.main-content { flex: 1; padding: 2rem; background: #0B0E11; color: white; }
|
||||
.menu-item { padding: 12px; color: #848E9C; text-decoration: none; display: flex; align-items: center; gap: 10px; border-radius: 4px; margin-bottom: 5px; }
|
||||
.menu-item:hover, .menu-item.active { background: #2B3139; color: white; }
|
||||
.badge { background: var(--danger-color); color: white; border-radius: 10px; padding: 2px 8px; font-size: 0.7rem; margin-left: auto; }
|
||||
.form-group { margin-bottom: 25px; background: #1E2329; padding: 20px; border-radius: 8px; border: 1px solid #2B3139; }
|
||||
.form-group label { display: block; margin-bottom: 10px; color: #848E9C; font-weight: bold; }
|
||||
input[type="text"], input[type="number"], select, textarea { width: 100%; padding: 10px; background: #0B0E11; border: 1px solid #2B3139; color: white; border-radius: 4px; outline: none; }
|
||||
.back-btn { color: #848E9C; text-decoration: none; font-size: 0.9rem; margin-bottom: 20px; display: inline-block; }
|
||||
.back-btn:hover { color: white; }
|
||||
.sidebar { width: 250px; background: #ffffff; border-right: 1px solid var(--border); padding: 1.5rem; }
|
||||
.main-content { flex: 1; padding: 2rem; background: #ffffff; }
|
||||
.menu-item { padding: 12px 15px; color: #474d57; text-decoration: none; display: flex; align-items: center; gap: 12px; border-radius: 8px; margin-bottom: 8px; transition: 0.2s; }
|
||||
.menu-item:hover, .menu-item.active { background: #f5f5f5; color: var(--primary); font-weight: bold; }
|
||||
.badge { background: #f6465d; color: white; border-radius: 10px; padding: 2px 8px; font-size: 0.7rem; margin-left: auto; }
|
||||
|
||||
.card { background: white; border-radius: 12px; border: 1px solid var(--border); padding: 25px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); margin-bottom: 2rem; }
|
||||
.form-group { margin-bottom: 20px; }
|
||||
.form-group label { display: block; margin-bottom: 8px; font-weight: 600; color: #474d57; }
|
||||
input[type="text"], input[type="number"], select, textarea { width: 100%; padding: 12px; border: 1px solid var(--border); border-radius: 8px; font-size: 1rem; outline: none; box-sizing: border-box; }
|
||||
input:focus, textarea:focus { border-color: var(--primary); }
|
||||
.btn { padding: 12px 30px; border-radius: 8px; font-weight: bold; cursor: pointer; border: none; transition: 0.2s; }
|
||||
.btn-primary { background: var(--primary); color: #000; }
|
||||
.btn-primary:hover { opacity: 0.9; }
|
||||
|
||||
.logo-preview { max-width: 200px; max-height: 100px; margin-bottom: 15px; border: 1px solid var(--border); padding: 10px; border-radius: 8px; background: #f0f0f0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="admin-layout">
|
||||
<div class="sidebar">
|
||||
<h3 style="color: white; margin-bottom: 2rem;">NovaEx 管理员</h3>
|
||||
<a href="index.php" class="menu-item"><i class="fas fa-chart-pie"></i> 仪表盘</a>
|
||||
<h2 style="color: var(--primary); margin-bottom: 2rem;">NovaEx Admin</h2>
|
||||
<a href="index.php" class="menu-item"><i class="fas fa-home"></i> 仪表盘</a>
|
||||
<a href="users.php" class="menu-item"><i class="fas fa-users"></i> 用户管理</a>
|
||||
<a href="agents.php" class="menu-item"><i class="fas fa-user-shield"></i> 代理管理</a>
|
||||
<a href="kyc.php" class="menu-item"><i class="fas fa-id-card"></i> KYC 审核</a>
|
||||
<a href="chat.php" class="menu-item">
|
||||
<i class="fas fa-headset"></i> 客服管理
|
||||
<i class="fas fa-comments"></i> 客服管理
|
||||
<?php if($unread_msgs > 0 || $pending_orders > 0): ?><span class="badge"><?php echo ($unread_msgs + $pending_orders); ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="options_orders.php" class="menu-item"><i class="fas fa-clock"></i> 秒合约</a>
|
||||
<a href="spot_orders.php" class="menu-item"><i class="fas fa-exchange-alt"></i> 现货交易</a>
|
||||
<a href="futures_orders.php" class="menu-item"><i class="fas fa-file-contract"></i> 合约交易</a>
|
||||
<a href="orders.php" class="menu-item"><i class="fas fa-wallet"></i> 充值记录</a>
|
||||
<a href="settings.php" class="menu-item active"><i class="fas fa-cog"></i> 系统设置</a>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<a href="index.php" class="back-btn"><i class="fas fa-arrow-left"></i> 返回</a>
|
||||
<h2>系统控制面板</h2>
|
||||
<h1 style="margin-bottom: 30px;">系统设置</h1>
|
||||
|
||||
<?php if(isset($message)): ?>
|
||||
<div style="background: rgba(0,255,0,0.1); color: #00ff00; padding: 15px; border-radius: 4px; margin-bottom: 20px;"><i class="fas fa-check-circle"></i> <?php echo $message; ?></div>
|
||||
<?php if($message): ?>
|
||||
<div style="background: #e6fcf5; color: #00c087; padding: 15px; border-radius: 8px; margin-bottom: 20px; border: 1px solid #00c087;"><i class="fas fa-check-circle"></i> <?php echo $message; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if($error): ?>
|
||||
<div style="background: #fff5f5; color: #f6465d; padding: 15px; border-radius: 8px; margin-bottom: 20px; border: 1px solid #f6465d;"><i class="fas fa-exclamation-circle"></i> <?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card">
|
||||
<h3>站点配置 (LOGO / 图标)</h3>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label>当前 LOGO</label>
|
||||
<?php if(isset($settings['site_logo'])): ?>
|
||||
<img src="../<?php echo $settings['site_logo']; ?>" class="logo-preview" alt="Logo">
|
||||
<?php else: ?>
|
||||
<div class="logo-preview" style="display: flex; align-items: center; justify-content: center; color: #ccc;">未设置 LOGO</div>
|
||||
<?php endif; ?>
|
||||
<input type="file" name="logo" accept="image/*">
|
||||
<p style="font-size: 0.8rem; color: #707a8a; margin-top: 5px;">建议尺寸: 200x60 像素。上传后将同步更新前端 LOGO 和网站图标。</p>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">上传并更新 LOGO</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form method="POST">
|
||||
<h3 style="margin: 30px 0 15px 0; color: #F0B90B;">1. 交易与胜率控制</h3>
|
||||
<div class="form-group">
|
||||
<label>全局胜率控制 (%)</label>
|
||||
<input type="number" name="settings[win_rate]" value="<?php echo $settings['win_rate'] ?? 70; ?>" min="0" max="100">
|
||||
<p style="font-size: 0.8rem; color: #5e6673; margin-top: 5px;">设置用户在秒合约/永续合约中的全局获利概率 (0-100)。</p>
|
||||
</div>
|
||||
|
||||
<h3 style="margin: 30px 0 15px 0; color: #F0B90B;">2. 价格操纵与插针控制</h3>
|
||||
<div class="form-group">
|
||||
<label>价格控制模式</label>
|
||||
<select name="settings[price_control]">
|
||||
<option value="0" <?php echo ($settings['price_control'] ?? '0') == '0' ? 'selected' : ''; ?>>实时行情 (API 自动同步)</option>
|
||||
<option value="1" <?php echo ($settings['price_control'] ?? '0') == '1' ? 'selected' : ''; ?>>强制控价 (所有用户看到指定价格)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div class="card">
|
||||
<h3>1. 交易与胜率控制</h3>
|
||||
<div class="form-group">
|
||||
<label>BTC 指定价格 ($)</label>
|
||||
<input type="number" name="settings[manual_btc_price]" value="<?php echo $settings['manual_btc_price'] ?? 0; ?>" step="0.01">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>BTC 插针价格 ($)</label>
|
||||
<input type="number" name="settings[pin_btc_price]" value="<?php echo $settings['pin_btc_price'] ?? 0; ?>" step="0.01">
|
||||
<p style="font-size: 0.75rem; color: #f6465d; margin-top: 5px;">插针价格用于瞬间触发用户的止盈或爆仓。</p>
|
||||
<label>全局胜率控制 (%)</label>
|
||||
<input type="number" name="settings[win_rate]" value="<?php echo $settings['win_rate'] ?? 70; ?>" min="0" max="100">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 style="margin: 30px 0 15px 0; color: #F0B90B;">3. 客服系统设置</h3>
|
||||
<div class="form-group">
|
||||
<label>客服自动问候语</label>
|
||||
<textarea name="settings[chat_greeting]" rows="3"><?php echo $settings['chat_greeting'] ?? '您好!欢迎咨询 NovaEx 官方客服,请问有什么可以帮您?如果是充值咨询,请提供您的充值金额和币种。'; ?></textarea>
|
||||
<p style="font-size: 0.8rem; color: #5e6673; margin-top: 5px;">用户首次进入聊天页面时看到的欢迎消息。</p>
|
||||
<div class="card">
|
||||
<h3>2. 价格操纵控制</h3>
|
||||
<div class="form-group">
|
||||
<label>价格控制模式</label>
|
||||
<select name="settings[price_control]">
|
||||
<option value="0" <?php echo ($settings['price_control'] ?? '0') == '0' ? 'selected' : ''; ?>>实时行情 (API 自动同步)</option>
|
||||
<option value="1" <?php echo ($settings['price_control'] ?? '0') == '1' ? 'selected' : ''; ?>>强制控价 (所有用户看到指定价格)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div class="form-group">
|
||||
<label>BTC 指定价格 ($)</label>
|
||||
<input type="number" name="settings[manual_btc_price]" value="<?php echo $settings['manual_btc_price'] ?? 0; ?>" step="0.01">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>BTC 插针价格 ($)</label>
|
||||
<input type="number" name="settings[pin_btc_price]" value="<?php echo $settings['pin_btc_price'] ?? 0; ?>" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 style="margin: 30px 0 15px 0; color: #F0B90B;">4. 其他配置</h3>
|
||||
<div class="form-group">
|
||||
<label>系统公告内容 (简体中文)</label>
|
||||
<input type="text" name="settings[announcement_zh]" value="<?php echo $settings['announcement_zh'] ?? ''; ?>" placeholder="输入显示在首页顶部的公告...">
|
||||
<div class="card">
|
||||
<h3>3. 客服与公告</h3>
|
||||
<div class="form-group">
|
||||
<label>客服自动问候语</label>
|
||||
<textarea name="settings[chat_greeting]" rows="3"><?php echo $settings['chat_greeting'] ?? '您好!欢迎咨询 NovaEx 官方客服。'; ?></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>系统公告内容 (简体中文)</label>
|
||||
<input type="text" name="settings[announcement_zh]" value="<?php echo $settings['announcement_zh'] ?? ''; ?>" placeholder="首页顶部公告...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-primary" style="padding: 12px 40px; font-weight: bold; border-radius: 8px; cursor: pointer; background: #f0b90b; color: black; border: none;">保存所有设置</button>
|
||||
<div style="text-align: right;">
|
||||
<button type="submit" class="btn btn-primary" style="font-size: 1.1rem; padding: 15px 60px;">保存所有系统设置</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
178
admin/users.php
178
admin/users.php
@ -34,17 +34,13 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['action'])) {
|
||||
$pdo->prepare($sql)->execute($params);
|
||||
} elseif ($action == 'adjust_balance') {
|
||||
$id = $_POST['id'];
|
||||
$type = $_POST['adjustment_type']; // 'up' or 'down'
|
||||
$type = $_POST['adjustment_type'];
|
||||
$amount = (float)$_POST['amount'];
|
||||
|
||||
if ($type == 'up') {
|
||||
$pdo->prepare("UPDATE users SET balance = balance + ? WHERE id = ?")->execute([$amount, $id]);
|
||||
} else {
|
||||
$pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ?")->execute([$amount, $id]);
|
||||
}
|
||||
} elseif ($action == 'delete_user') {
|
||||
$id = $_POST['id'];
|
||||
$pdo->prepare("DELETE FROM users WHERE id = ?")->execute([$id]);
|
||||
} elseif ($action == 'toggle_status') {
|
||||
$id = $_POST['id'];
|
||||
$user = $pdo->prepare("SELECT status FROM users WHERE id = ?");
|
||||
@ -59,13 +55,13 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['action'])) {
|
||||
$users = $pdo->query("SELECT * FROM users ORDER BY id DESC")->fetchAll();
|
||||
$unread_msgs = $pdo->query("SELECT COUNT(*) FROM messages WHERE sender = 'user' AND is_read = 0")->fetchColumn();
|
||||
$pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN ('matching', 'submitting')")->fetchColumn();
|
||||
$pending_kyc = $pdo->query("SELECT COUNT(*) FROM users WHERE kyc_status = 1")->fetchColumn();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>用户管理 - NovaEx 管理后台</title>
|
||||
<link rel="stylesheet" href="../assets/css/custom.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
:root { --primary: #f0b90b; --bg: #ffffff; --text: #1e2329; --border: #eaecef; }
|
||||
@ -80,14 +76,13 @@ $pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN
|
||||
.card { background: white; border-radius: 12px; border: 1px solid var(--border); padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); }
|
||||
.table { width: 100%; border-collapse: collapse; margin-top: 1.5rem; }
|
||||
.table th, .table td { padding: 15px; text-align: left; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
|
||||
.table th { background: #f9fafb; color: #707a8a; font-weight: 600; text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.5px; }
|
||||
.table th { background: #f9fafb; color: #707a8a; font-weight: 600; text-transform: uppercase; font-size: 0.75rem; }
|
||||
|
||||
.btn { padding: 8px 16px; border-radius: 6px; font-size: 0.85rem; border: none; cursor: pointer; font-weight: 500; transition: 0.2s; display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
|
||||
.btn-primary { background: var(--primary); color: black; }
|
||||
.btn-danger { background: #f6465d; color: white; }
|
||||
.btn-info { background: #2f80ed; color: white; }
|
||||
.btn-success { background: #00c087; color: white; }
|
||||
.btn-sm { padding: 5px 10px; font-size: 0.75rem; }
|
||||
|
||||
.status-badge { padding: 4px 8px; border-radius: 4px; font-size: 0.75rem; font-weight: bold; }
|
||||
.status-active { background: #e6fcf5; color: #00c087; }
|
||||
@ -95,11 +90,9 @@ $pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN
|
||||
|
||||
.modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-content { background: white; width: 550px; padding: 30px; border-radius: 16px; box-shadow: 0 20px 40px rgba(0,0,0,0.2); }
|
||||
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; }
|
||||
.form-group { margin-bottom: 20px; }
|
||||
.form-group label { display: block; margin-bottom: 8px; font-weight: 600; color: #474d57; font-size: 0.9rem; }
|
||||
.form-group label { display: block; margin-bottom: 8px; font-weight: 600; color: #474d57; }
|
||||
.form-group input, .form-group select { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; font-size: 1rem; outline: none; box-sizing: border-box; }
|
||||
.form-group input:focus { border-color: var(--primary); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -108,9 +101,11 @@ $pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN
|
||||
<h2 style="color: var(--primary); margin-bottom: 2rem;">NovaEx Admin</h2>
|
||||
<a href="index.php" class="menu-item"><i class="fas fa-home"></i> 仪表盘</a>
|
||||
<a href="users.php" class="menu-item active"><i class="fas fa-users"></i> 用户管理</a>
|
||||
<a href="kyc.php" class="menu-item"><i class="fas fa-id-card"></i> KYC 审核</a>
|
||||
<a href="chat.php" class="menu-item">
|
||||
<i class="fas fa-comments"></i> 客服管理
|
||||
<a href="agents.php" class="menu-item"><i class="fas fa-user-shield"></i> 代理管理</a>
|
||||
<a href="kyc.php" class="menu-item"><i class="fas fa-id-card"></i> KYC 审核
|
||||
<?php if($pending_kyc > 0): ?><span class="badge"><?php echo $pending_kyc; ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="chat.php" class="menu-item"><i class="fas fa-comments"></i> 客服管理
|
||||
<?php if($unread_msgs > 0 || $pending_orders > 0): ?><span class="badge"><?php echo ($unread_msgs + $pending_orders); ?></span><?php endif; ?>
|
||||
</a>
|
||||
<a href="options_orders.php" class="menu-item"><i class="fas fa-clock"></i> 秒合约</a>
|
||||
@ -146,16 +141,14 @@ $pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN
|
||||
<div style="font-weight: bold;"><?php echo $user['uid']; ?></div>
|
||||
<div style="font-size: 0.8rem; color: #707a8a;"><?php echo htmlspecialchars($user['username']); ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="color: #00c087; font-weight: bold;"><?php echo number_format($user['balance'], 2); ?></div>
|
||||
</td>
|
||||
<td><div style="color: #00c087; font-weight: bold;"><?php echo number_format($user['balance'], 2); ?></div></td>
|
||||
<td><?php echo $user['credit_score']; ?></td>
|
||||
<td>
|
||||
<?php
|
||||
<?php
|
||||
$wc = $user['win_loss_control'];
|
||||
$wc_label = ['none' => '正常', 'win' => '起盈', 'loss' => '起亏'];
|
||||
$wc_class = ['none' => '', 'win' => 'color: #00c087; font-weight: bold;', 'loss' => 'color: #f6465d; font-weight: bold;'];
|
||||
echo "<span style='{$wc_class[$wc]}'>{$wc_label[$wc]}</span>";
|
||||
$labels = ['none' => '正常', 'win' => '起盈', 'loss' => '起亏'];
|
||||
$colors = ['none' => '#474d57', 'win' => '#00c087', 'loss' => '#f6465d'];
|
||||
echo "<span style='color: {$colors[$wc]}; font-weight: bold;'>{$labels[$wc]}</span>";
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
@ -164,22 +157,17 @@ $pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-size: 0.8rem;"><?php echo date('Y-m-d H:i', strtotime($user['created_at'])); ?></div>
|
||||
<div style="font-size: 0.8rem;"><?php echo $user['created_at']; ?></div>
|
||||
<div style="font-size: 0.75rem; color: #848e9c;"><?php echo $user['last_ip'] ?: '127.0.0.1'; ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<button class="btn btn-sm btn-info" onclick='editUser(<?php echo json_encode($user); ?>)' title="编辑"><i class="fas fa-edit"></i></button>
|
||||
<button class="btn btn-sm btn-success" onclick="adjustBalance(<?php echo $user['id']; ?>, '<?php echo $user['username']; ?>')" title="上下分"><i class="fas fa-wallet"></i></button>
|
||||
<button class="btn btn-info btn-sm" onclick='editUser(<?php echo json_encode($user); ?>)'><i class="fas fa-edit"></i></button>
|
||||
<button class="btn btn-success btn-sm" onclick="adjustBalance(<?php echo $user['id']; ?>, '<?php echo $user['username']; ?>')"><i class="fas fa-wallet"></i></button>
|
||||
<form method="POST" style="display: inline;" onsubmit="return confirm('确定要执行此操作吗?')">
|
||||
<input type="hidden" name="id" value="<?php echo $user['id']; ?>">
|
||||
<input type="hidden" name="action" value="toggle_status">
|
||||
<button type="submit" class="btn btn-sm btn-info" title="冻结/解冻"><i class="fas fa-ban"></i></button>
|
||||
</form>
|
||||
<form method="POST" style="display: inline;" onsubmit="return confirm('确定要删除该用户吗?此操作不可逆!')">
|
||||
<input type="hidden" name="id" value="<?php echo $user['id']; ?>">
|
||||
<input type="hidden" name="action" value="delete_user">
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="删除"><i class="fas fa-trash"></i></button>
|
||||
<button type="submit" class="btn btn-info btn-sm" title="锁定/解锁"><i class="fas fa-ban"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
@ -191,13 +179,10 @@ $pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Modal -->
|
||||
<!-- Add User Modal -->
|
||||
<div id="addModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>添加新用户</h3>
|
||||
<i class="fas fa-times" onclick="hideModal('addModal')" style="cursor: pointer;"></i>
|
||||
</div>
|
||||
<h2>添加新用户</h2>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="add_user">
|
||||
<div class="form-group">
|
||||
@ -205,135 +190,120 @@ $pending_orders = $pdo->query("SELECT COUNT(*) FROM fiat_orders WHERE status IN
|
||||
<input type="text" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>登录密码</label>
|
||||
<label>密码</label>
|
||||
<input type="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group" style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
||||
<div>
|
||||
<label>初始余额 (USDT)</label>
|
||||
<input type="number" name="balance" step="0.01" value="0">
|
||||
</div>
|
||||
<div>
|
||||
<label>初始信用分</label>
|
||||
<input type="number" name="credit_score" value="80">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>初始余额</label>
|
||||
<input type="number" name="balance" step="0.01" value="0.00">
|
||||
</div>
|
||||
<div class="modal-footer" style="text-align: right; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('addModal')">取消</button>
|
||||
<button type="submit" class="btn btn-primary">确认添加</button>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('addModal')" style="background: #eee;">取消</button>
|
||||
<button type="submit" class="btn btn-primary">确定添加</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Modal -->
|
||||
<!-- Edit User Modal -->
|
||||
<div id="editModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>编辑用户信息</h3>
|
||||
<i class="fas fa-times" onclick="hideModal('editModal')" style="cursor: pointer;"></i>
|
||||
</div>
|
||||
<h2>编辑用户信息</h2>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="update_user">
|
||||
<input type="hidden" name="id" id="edit_id">
|
||||
<input type="hidden" name="id" id="edit-id">
|
||||
<div class="form-group">
|
||||
<label>用户名</label>
|
||||
<input type="text" name="username" id="edit_username" required>
|
||||
<input type="text" name="username" id="edit-username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>修改密码 (不填则不修改)</label>
|
||||
<input type="password" name="password" placeholder="请输入新密码">
|
||||
<label>修改密码 (留空则不修改)</label>
|
||||
<input type="password" name="password" placeholder="******">
|
||||
</div>
|
||||
<div class="form-group" style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
||||
<div>
|
||||
<label>余额 (USDT)</label>
|
||||
<input type="number" name="balance" id="edit_balance" step="0.00000001">
|
||||
<div class="form-row" style="display: flex; gap: 15px;">
|
||||
<div class="form-group" style="flex: 1;">
|
||||
<label>余额</label>
|
||||
<input type="number" name="balance" id="edit-balance" step="0.01">
|
||||
</div>
|
||||
<div>
|
||||
<div class="form-group" style="flex: 1;">
|
||||
<label>信用分</label>
|
||||
<input type="number" name="credit_score" id="edit_credit_score">
|
||||
<input type="number" name="credit_score" id="edit-credit">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
||||
<div>
|
||||
<div class="form-row" style="display: flex; gap: 15px;">
|
||||
<div class="form-group" style="flex: 1;">
|
||||
<label>输赢控制</label>
|
||||
<select name="win_loss_control" id="edit_win_loss">
|
||||
<select name="win_loss_control" id="edit-win-loss">
|
||||
<option value="none">正常</option>
|
||||
<option value="win">起盈</option>
|
||||
<option value="loss">起亏</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>账户状态</label>
|
||||
<select name="status" id="edit_status">
|
||||
<div class="form-group" style="flex: 1;">
|
||||
<label>状态</label>
|
||||
<select name="status" id="edit-status">
|
||||
<option value="active">正常</option>
|
||||
<option value="disabled">冻结</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="text-align: right; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('editModal')">取消</button>
|
||||
<button type="submit" class="btn btn-primary">确认保存</button>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('editModal')" style="background: #eee;">取消</button>
|
||||
<button type="submit" class="btn btn-primary">保存修改</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Balance Adjust Modal -->
|
||||
<div id="adjustModal" class="modal">
|
||||
<!-- Adjust Balance Modal -->
|
||||
<div id="balanceModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>上下分 - <span id="adjust_name"></span></h3>
|
||||
<i class="fas fa-times" onclick="hideModal('adjustModal')" style="cursor: pointer;"></i>
|
||||
</div>
|
||||
<h2>资金调整 - <span id="adj-name"></span></h2>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="adjust_balance">
|
||||
<input type="hidden" name="id" id="adjust_id">
|
||||
<input type="hidden" name="id" id="adj-id">
|
||||
<div class="form-group">
|
||||
<label>操作类型</label>
|
||||
<label>调整类型</label>
|
||||
<select name="adjustment_type">
|
||||
<option value="up">上分 (增加余额)</option>
|
||||
<option value="down">下分 (扣除余额)</option>
|
||||
<option value="up">增加余额 (+)</option>
|
||||
<option value="down">减少余额 (-)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>金额 (USDT)</label>
|
||||
<input type="number" name="amount" step="0.01" required placeholder="请输入金额">
|
||||
<label>调整金额 (USDT)</label>
|
||||
<input type="number" name="amount" step="0.01" required placeholder="0.00">
|
||||
</div>
|
||||
<div class="modal-footer" style="text-align: right; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('adjustModal')">取消</button>
|
||||
<button type="submit" class="btn btn-primary">确认提交</button>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<button type="button" class="btn" onclick="hideModal('balanceModal')" style="background: #eee;">取消</button>
|
||||
<button type="submit" class="btn btn-success">确认调整</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showModal(id) {
|
||||
document.getElementById(id).style.display = 'flex';
|
||||
}
|
||||
function hideModal(id) {
|
||||
document.getElementById(id).style.display = 'none';
|
||||
}
|
||||
function showModal(id) { document.getElementById(id).style.display = 'flex'; }
|
||||
function hideModal(id) { document.getElementById(id).style.display = 'none'; }
|
||||
|
||||
function editUser(user) {
|
||||
document.getElementById('edit_id').value = user.id;
|
||||
document.getElementById('edit_username').value = user.username;
|
||||
document.getElementById('edit_balance').value = user.balance;
|
||||
document.getElementById('edit_credit_score').value = user.credit_score;
|
||||
document.getElementById('edit_win_loss').value = user.win_loss_control;
|
||||
document.getElementById('edit_status').value = user.status;
|
||||
document.getElementById('edit-id').value = user.id;
|
||||
document.getElementById('edit-username').value = user.username;
|
||||
document.getElementById('edit-balance').value = user.balance;
|
||||
document.getElementById('edit-credit').value = user.credit_score;
|
||||
document.getElementById('edit-win-loss').value = user.win_loss_control;
|
||||
document.getElementById('edit-status').value = user.status;
|
||||
showModal('editModal');
|
||||
}
|
||||
|
||||
function adjustBalance(id, name) {
|
||||
document.getElementById('adjust_id').value = id;
|
||||
document.getElementById('adjust_name').innerText = name;
|
||||
showModal('adjustModal');
|
||||
document.getElementById('adj-id').value = id;
|
||||
document.getElementById('adj-name').innerText = name;
|
||||
showModal('balanceModal');
|
||||
}
|
||||
|
||||
// Close modal on outside click
|
||||
window.onclick = function(event) {
|
||||
if (event.target.className === 'modal') {
|
||||
event.target.style.display = 'none';
|
||||
event.target.style.display = "none";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -15,7 +15,8 @@ $pdo = db();
|
||||
|
||||
// Auto-settle orders that are due
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$stmt = $pdo->prepare("SELECT o.*, u.win_loss_control FROM option_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND o.settle_at <= ?");
|
||||
// Fetch orders that are pending and due, joined with user win_loss_control
|
||||
$stmt = $pdo->prepare("SELECT o.*, u.win_loss_control as user_control FROM option_orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND o.settle_at <= ?");
|
||||
$stmt->execute([$now]);
|
||||
$due_orders = $stmt->fetchAll();
|
||||
|
||||
@ -23,15 +24,20 @@ foreach ($due_orders as $order) {
|
||||
$result = 'loss';
|
||||
$profit = 0;
|
||||
|
||||
// Win/Loss Control Logic
|
||||
if ($order['win_loss_control'] === 'win') {
|
||||
// Win/Loss Control Logic: Order-level control overrides User-level control
|
||||
$final_control = 'none';
|
||||
if ($order['control'] !== 'none') {
|
||||
$final_control = $order['control'];
|
||||
} elseif ($order['user_control'] !== 'none') {
|
||||
$final_control = $order['user_control'];
|
||||
}
|
||||
|
||||
if ($final_control === 'win') {
|
||||
$result = 'win';
|
||||
} elseif ($order['win_loss_control'] === 'loss') {
|
||||
} elseif ($final_control === 'loss') {
|
||||
$result = 'loss';
|
||||
} else {
|
||||
// Normal: Random or could be based on real price.
|
||||
// For simplicity in these "second contract" systems, it's often slightly biased or random if not controlled.
|
||||
// Let's do 50/50 for "none" control.
|
||||
// Default behavior if no control is set: 50/50 chance
|
||||
$result = (rand(0, 100) > 50) ? 'win' : 'loss';
|
||||
}
|
||||
|
||||
@ -39,24 +45,26 @@ foreach ($due_orders as $order) {
|
||||
$profit = $order['amount'] * $order['profit_rate'];
|
||||
$total_return = $order['amount'] + $profit;
|
||||
|
||||
// Add balance
|
||||
// Add balance to user
|
||||
$stmt_bal = $pdo->prepare("UPDATE users SET balance = balance + ? WHERE id = ?");
|
||||
$stmt_bal->execute([$total_return, $order['user_id']]);
|
||||
|
||||
// Update closing price slightly higher or lower based on direction
|
||||
$closing_price = ($order['direction'] === 'up') ? $order['opening_price'] * 1.001 : $order['opening_price'] * 0.999;
|
||||
// Set closing price slightly higher or lower than opening price to match result
|
||||
$variation = (float)($order['opening_price'] * 0.0001 * rand(1, 10));
|
||||
$closing_price = ($order['direction'] === 'up') ? $order['opening_price'] + $variation : $order['opening_price'] - $variation;
|
||||
} else {
|
||||
$profit = -$order['amount'];
|
||||
$closing_price = ($order['direction'] === 'up') ? $order['opening_price'] * 0.999 : $order['opening_price'] * 1.001;
|
||||
$variation = (float)($order['opening_price'] * 0.0001 * rand(1, 10));
|
||||
$closing_price = ($order['direction'] === 'up') ? $order['opening_price'] - $variation : $order['opening_price'] + $variation;
|
||||
}
|
||||
|
||||
$stmt_update = $pdo->prepare("UPDATE option_orders SET status = 'completed', result = ?, profit = ?, closing_price = ? WHERE id = ?");
|
||||
$stmt_update->execute([$result, $profit, $closing_price, $order['id']]);
|
||||
}
|
||||
|
||||
// Fetch orders
|
||||
// Fetch current orders for the user to return to frontend
|
||||
$stmt = $pdo->prepare("SELECT * FROM option_orders WHERE user_id = ? AND status = ? ORDER BY created_at DESC");
|
||||
$stmt->execute([$user_id, $status]);
|
||||
$orders = $stmt->fetchAll();
|
||||
|
||||
echo json_encode(['success' => true, 'data' => $orders]);
|
||||
echo json_encode(['success' => true, 'data' => $orders]);
|
||||
@ -1,54 +1,68 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once '../db/config.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
require_once '../db/config.php';
|
||||
session_start();
|
||||
|
||||
$user_id = $_SESSION['user_id'] ?? null;
|
||||
if (!$user_id) {
|
||||
echo json_encode(['success' => false, 'error' => '未登录']);
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo json_encode(['success' => false, 'error' => 'Please login first']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
$symbol = $data['symbol'] ?? '';
|
||||
$amount = floatval($data['amount'] ?? 0);
|
||||
$direction = $data['direction'] ?? '';
|
||||
$duration = intval($data['duration'] ?? 0);
|
||||
$profit_rate = floatval($data['profit_rate'] ?? 0);
|
||||
$opening_price = floatval($data['opening_price'] ?? 0);
|
||||
|
||||
if (!$symbol || $amount <= 0 || !in_array($direction, ['up', 'down']) || !in_array($duration, [60, 90, 120, 180, 300])) {
|
||||
echo json_encode(['success' => false, 'error' => '参数错误']);
|
||||
$symbol = $data['symbol'] ?? '';
|
||||
$amount = (float)($data['amount'] ?? 0);
|
||||
$direction = $data['direction'] ?? '';
|
||||
$duration = (int)($data['duration'] ?? 60);
|
||||
$opening_price = (float)($data['opening_price'] ?? 0);
|
||||
|
||||
// Updated Validate duration and profit rates as per user request
|
||||
// 60s/8%、90s/12%、120s/20%、180s/20%、300s/32%
|
||||
$valid_durations = [
|
||||
60 => ['profit' => 0.08, 'min' => 10],
|
||||
90 => ['profit' => 0.12, 'min' => 10],
|
||||
120 => ['profit' => 0.20, 'min' => 10],
|
||||
180 => ['profit' => 0.20, 'min' => 10],
|
||||
300 => ['profit' => 0.32, 'min' => 10],
|
||||
];
|
||||
|
||||
if (!isset($valid_durations[$duration])) {
|
||||
echo json_encode(['success' => false, 'error' => 'Invalid duration']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
$profit_rate = $valid_durations[$duration]['profit'];
|
||||
$min_amount = $valid_durations[$duration]['min'];
|
||||
|
||||
// Check balance
|
||||
$stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ? FOR UPDATE");
|
||||
if ($amount < $min_amount) {
|
||||
echo json_encode(['success' => false, 'error' => "Minimum amount is {$min_amount} USDT"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = db();
|
||||
$db->beginTransaction();
|
||||
|
||||
try {
|
||||
$stmt = $db->prepare("SELECT balance FROM users WHERE id = ? FOR UPDATE");
|
||||
$stmt->execute([$user_id]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
if (!$user || $user['balance'] < $amount) {
|
||||
throw new Exception('余额不足');
|
||||
throw new Exception('Insufficient balance');
|
||||
}
|
||||
|
||||
// Deduct balance
|
||||
$stmt = $pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ?");
|
||||
$stmt->execute([$amount, $user_id]);
|
||||
$new_balance = $user['balance'] - $amount;
|
||||
$db->prepare("UPDATE users SET balance = ? WHERE id = ?")->execute([$new_balance, $user_id]);
|
||||
|
||||
// Create order
|
||||
$settle_at = date('Y-m-d H:i:s', time() + $duration);
|
||||
$stmt = $pdo->prepare("INSERT INTO option_orders (user_id, symbol, amount, direction, duration, profit_rate, opening_price, status, settle_at) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?)");
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO option_orders (user_id, symbol, amount, direction, duration, profit_rate, opening_price, status, settle_at) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?)");
|
||||
$stmt->execute([$user_id, $symbol, $amount, $direction, $duration, $profit_rate, $opening_price, $settle_at]);
|
||||
|
||||
$pdo->commit();
|
||||
echo json_encode(['success' => true, 'new_balance' => $user['balance'] - $amount]);
|
||||
|
||||
$db->commit();
|
||||
echo json_encode(['success' => true, 'new_balance' => $new_balance]);
|
||||
} catch (Exception $e) {
|
||||
$pdo->rollBack();
|
||||
$db->rollBack();
|
||||
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
BIN
assets/pasted-20260212-081234-b39bf249.png
Normal file
BIN
assets/pasted-20260212-081234-b39bf249.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 238 KiB |
BIN
assets/pasted-20260212-082507-886037c0.png
Normal file
BIN
assets/pasted-20260212-082507-886037c0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/pasted-20260212-083227-eeea9763.png
Normal file
BIN
assets/pasted-20260212-083227-eeea9763.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
BIN
assets/pasted-20260212-085504-87e784a3.png
Normal file
BIN
assets/pasted-20260212-085504-87e784a3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
286
futures.php
286
futures.php
@ -27,46 +27,69 @@ if ($user_id) {
|
||||
--input-bg: #1e2329;
|
||||
}
|
||||
|
||||
body { background-color: var(--bg-color); color: var(--text-primary); font-family: 'PingFang SC', sans-serif; margin: 0; overflow-y: auto !important; }
|
||||
body { background-color: var(--bg-color); color: var(--text-primary); font-family: 'Inter', 'PingFang SC', sans-serif; margin: 0; overflow-y: auto !important; }
|
||||
|
||||
.trading-layout { display: flex; gap: 1px; background: var(--border-color); min-height: calc(100vh - 64px); }
|
||||
.panel { background: var(--panel-bg); display: flex; flex-direction: column; }
|
||||
|
||||
/* Market Panel */
|
||||
.market-panel { width: 280px; flex-shrink: 0; border-right: 1px solid var(--border-color); }
|
||||
#pairs-list { height: 600px; overflow-y: auto; }
|
||||
.pair-item { display: flex; justify-content: space-between; padding: 10px 12px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.02); }
|
||||
.pair-item.active { background: rgba(79, 172, 254, 0.1); }
|
||||
|
||||
/* Center Panel */
|
||||
.center-panel { flex: 1; background: var(--bg-color); display: flex; flex-direction: column; }
|
||||
.info-bar { height: 60px; display: flex; align-items: center; padding: 0 15px; gap: 15px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); flex-wrap: wrap; }
|
||||
.chart-container { height: 420px; background: var(--bg-color); border-bottom: 1px solid var(--border-color); }
|
||||
.market-panel { width: 300px; flex-shrink: 0; border-right: 1px solid var(--border-color); }
|
||||
#pairs-list { height: calc(100vh - 120px); overflow-y: auto; scrollbar-width: thin; }
|
||||
.pair-item { display: flex; align-items: center; padding: 10px 16px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.02); transition: 0.2s; }
|
||||
.pair-item:hover { background: rgba(255,255,255,0.05); }
|
||||
.pair-item.active { background: rgba(79, 172, 254, 0.08); border-left: 3px solid var(--accent-color); }
|
||||
.pair-icon { width: 24px; height: 24px; margin-right: 12px; border-radius: 50%; }
|
||||
|
||||
.order-form-panel { padding: 20px; background: var(--panel-bg); border-bottom: 1px solid var(--border-color); }
|
||||
.order-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; }
|
||||
.input-row { background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 4px; display: flex; align-items: center; margin-bottom: 10px; padding: 8px 12px; }
|
||||
.input-row input { flex: 1; background: transparent; border: none; color: white; text-align: right; outline: none; font-size: 14px; }
|
||||
.btn-trade { padding: 12px; border: none; border-radius: 6px; font-weight: bold; font-size: 15px; cursor: pointer; color: white; }
|
||||
/* Center Panel */
|
||||
.center-panel { flex: 1; background: var(--bg-color); display: flex; flex-direction: column; min-width: 0; }
|
||||
.info-bar { height: 66px; display: flex; align-items: center; padding: 0 20px; gap: 25px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); }
|
||||
.chart-container { height: 550px; background: var(--bg-color); border-bottom: 1px solid var(--border-color); }
|
||||
|
||||
.order-form-panel { padding: 25px; background: var(--panel-bg); border-bottom: 1px solid var(--border-color); }
|
||||
.order-form-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 40px; }
|
||||
.input-row { background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 6px; display: flex; align-items: center; margin-bottom: 12px; padding: 10px 15px; transition: 0.2s; }
|
||||
.input-row:focus-within { border-color: var(--accent-color); }
|
||||
.input-row input { flex: 1; background: transparent; border: none; color: white; text-align: right; outline: none; font-size: 14px; font-weight: 600; }
|
||||
.btn-trade { padding: 14px; border: none; border-radius: 8px; font-weight: bold; font-size: 16px; cursor: pointer; color: white; transition: 0.3s; margin-top: 10px; }
|
||||
.btn-trade:hover { opacity: 0.9; transform: translateY(-1px); }
|
||||
|
||||
/* Order Book Panel */
|
||||
.order-book-panel { width: 320px; flex-shrink: 0; border-left: 1px solid var(--border-color); display: flex; flex-direction: column; }
|
||||
.ob-header { padding: 12px 16px; font-size: 12px; color: var(--text-secondary); border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; font-weight: 600; }
|
||||
.ob-row { display: flex; justify-content: space-between; padding: 4px 16px; font-size: 12px; position: relative; font-family: 'Roboto Mono', monospace; cursor: pointer; }
|
||||
.ob-row:hover { background: rgba(255,255,255,0.05); }
|
||||
.ob-vol-bar { position: absolute; top: 0; right: 0; bottom: 0; z-index: 0; opacity: 0.15; transition: width 0.3s; }
|
||||
|
||||
/* Tabs */
|
||||
.tab-btn { background: none; border: none; color: var(--text-secondary); padding: 15px 20px; font-size: 14px; font-weight: 600; cursor: pointer; position: relative; transition: 0.2s; white-space: nowrap; }
|
||||
.tab-btn.active { color: var(--accent-color); }
|
||||
.tab-btn.active::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 3px; background: var(--accent-color); border-radius: 3px 3px 0 0; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 1400px) {
|
||||
.market-panel { width: 260px; }
|
||||
.order-book-panel { width: 280px; }
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
.market-panel { display: none; }
|
||||
}
|
||||
@media (max-width: 992px) {
|
||||
.trading-layout { flex-direction: column; }
|
||||
.order-book-panel { display: none; }
|
||||
.chart-container { height: 350px; }
|
||||
.order-form-grid { grid-template-columns: 1fr; gap: 10px; }
|
||||
.info-bar { height: auto; padding: 10px 15px; }
|
||||
.order-book-panel { width: 100%; border-left: none; border-top: 1px solid var(--border-color); }
|
||||
.chart-container { height: 400px; }
|
||||
.order-form-grid { grid-template-columns: 1fr; gap: 20px; }
|
||||
.info-bar { height: auto; padding: 15px; flex-wrap: wrap; gap: 15px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="trading-layout">
|
||||
<!-- Left Panel -->
|
||||
<div class="panel market-panel">
|
||||
<div style="padding: 12px; border-bottom: 1px solid var(--border-color);">
|
||||
<input type="text" id="market-search" placeholder="搜索合约" style="width: 100%; background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 8px 12px; border-radius: 6px; font-size: 13px;">
|
||||
<div style="padding: 15px; border-bottom: 1px solid var(--border-color);">
|
||||
<div style="position: relative;">
|
||||
<i class="fas fa-search" style="position: absolute; left: 12px; top: 12px; color: var(--text-secondary); font-size: 14px;"></i>
|
||||
<input type="text" id="market-search" placeholder="<?php echo __('search_contract'); ?>" style="width: 100%; background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 10px 12px 10px 35px; border-radius: 8px; font-size: 13px; outline: none;">
|
||||
</div>
|
||||
</div>
|
||||
<div id="pairs-list"></div>
|
||||
</div>
|
||||
@ -74,20 +97,20 @@ if ($user_id) {
|
||||
<!-- Center Panel -->
|
||||
<div class="panel center-panel">
|
||||
<div class="info-bar">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<img id="current-logo" src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" width="28" height="28" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<img id="current-logo" src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" width="32" height="32" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<div>
|
||||
<div id="current-pair-display" style="font-size: 15px; font-weight: bold;">BTC/USDT 永续</div>
|
||||
<div id="leverage-display" style="font-size: 11px; color: var(--accent-color); cursor: pointer;" onclick="showLevModal()">20x</div>
|
||||
<div id="current-pair-display" style="font-size: 18px; font-weight: 800; letter-spacing: -0.5px;">BTC/USDT <?php echo __('perpetual'); ?></div>
|
||||
<div id="leverage-display" style="font-size: 12px; color: var(--accent-color); cursor: pointer; font-weight: 600;" onclick="showLevModal()"><span id="leverage-val-info">20</span>x</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column;">
|
||||
<span id="last-price" style="font-size: 18px; font-weight: bold; color: var(--up-color);">--</span>
|
||||
<span id="price-change" style="font-size: 11px;">--</span>
|
||||
<span id="last-price" style="font-size: 18px; font-weight: 700; color: var(--up-color); font-family: 'Roboto Mono', monospace;">--</span>
|
||||
<span id="price-change" style="font-size: 11px; font-weight: 600;">--</span>
|
||||
</div>
|
||||
<div style="margin-left: auto; display: flex; gap: 15px; font-size: 11px;" class="desktop-only">
|
||||
<div style="color: var(--text-secondary);">标记 <span id="mark-price" style="color: white;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h额 <span id="vol-24h" style="color: white;">--</span></div>
|
||||
<div style="margin-left: auto; display: flex; gap: 25px; font-size: 12px;" class="desktop-only">
|
||||
<div style="color: var(--text-secondary);">Mark <span id="mark-price" style="color: white; font-weight: 600; display: block; margin-top: 4px;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h Vol <span id="vol-24h" style="color: white; font-weight: 600; display: block; margin-top: 4px;">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -97,58 +120,58 @@ if ($user_id) {
|
||||
|
||||
<div class="center-content">
|
||||
<div class="order-form-panel">
|
||||
<div style="display: flex; gap: 10px; margin-bottom: 15px;">
|
||||
<button class="ctrl-btn active" id="margin-isolated" onclick="setMargin('isolated')" style="background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 5px 12px; border-radius: 4px; font-size: 12px; cursor: pointer;">逐仓</button>
|
||||
<button class="ctrl-btn" onclick="showLevModal()" style="background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 5px 12px; border-radius: 4px; font-size: 12px; cursor: pointer;"><span id="leverage-val">20</span>x</button>
|
||||
<div style="display: flex; gap: 15px; margin-left: 10px; align-items: center;">
|
||||
<button onclick="setOrderType('limit')" id="order-type-limit" style="background: none; border: none; color: var(--text-secondary); font-size: 13px; cursor: pointer;">限价</button>
|
||||
<button onclick="setOrderType('market')" id="order-type-market" style="background: none; border: none; color: var(--accent-color); font-weight: bold; font-size: 13px; cursor: pointer;">市价</button>
|
||||
<div style="display: flex; gap: 12px; margin-bottom: 20px; align-items: center;">
|
||||
<button class="ctrl-btn active" id="margin-isolated" onclick="setMargin('isolated')" style="background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 6px 15px; border-radius: 6px; font-size: 13px; cursor: pointer; font-weight: 600;"><?php echo __('isolated'); ?></button>
|
||||
<button class="ctrl-btn" onclick="showLevModal()" style="background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 6px 15px; border-radius: 6px; font-size: 13px; cursor: pointer; font-weight: 600;"><span id="leverage-val">20</span>x</button>
|
||||
<div style="display: flex; gap: 20px; margin-left: 15px; align-items: center;">
|
||||
<button onclick="setOrderType('limit')" id="order-type-limit" style="background: none; border: none; color: var(--text-secondary); font-size: 14px; cursor: pointer; font-weight: 700;"><?php echo __('limit'); ?></button>
|
||||
<button onclick="setOrderType('market')" id="order-type-market" style="background: none; border: none; color: var(--accent-color); font-weight: 700; font-size: 14px; cursor: pointer;"><?php echo __('market'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-form-grid">
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 8px;">
|
||||
<span style="color: var(--text-secondary);">可用余额</span>
|
||||
<span id="available-bal" style="color: white;"><?php echo number_format($balance, 2); ?> USDT</span>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 10px;">
|
||||
<span style="color: var(--text-secondary);"><?php echo __('available'); ?></span>
|
||||
<span id="available-bal" style="color: white; font-weight: 600;"><?php echo number_format($balance, 2); ?> USDT</span>
|
||||
</div>
|
||||
<div class="input-row" id="price-row" style="display: none;">
|
||||
<span style="color: var(--text-secondary); font-size: 13px; width: 40px;">价格</span>
|
||||
<span style="color: var(--text-secondary); font-size: 13px; width: 60px; font-weight: 600;"><?php echo __('price'); ?></span>
|
||||
<input type="number" id="order-price" placeholder="0.00">
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<span style="color: var(--text-secondary); font-size: 13px; width: 40px;">数量</span>
|
||||
<input type="number" id="order-amount" placeholder="张数">
|
||||
<span style="color: var(--text-secondary); font-size: 13px; width: 60px; font-weight: 600;"><?php echo __('amount'); ?></span>
|
||||
<input type="number" id="order-amount" placeholder="Cont">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="margin: 10px 0;">
|
||||
<input type="range" min="0" max="100" value="0" id="order-slider" style="width: 100%; accent-color: var(--accent-color);" oninput="updateFromSlider(this.value)">
|
||||
<div style="display: flex; justify-content: space-between; font-size: 10px; color: var(--text-secondary); margin-top: 5px;">
|
||||
<span onclick="setSlider(0)">0%</span><span onclick="setSlider(25)">25%</span><span onclick="setSlider(50)">50%</span><span onclick="setSlider(75)">75%</span><span onclick="setSlider(100)">100%</span>
|
||||
<div style="margin: 10px 0 20px;">
|
||||
<input type="range" min="0" max="100" value="0" id="order-slider" style="width: 100%; accent-color: var(--accent-color); cursor: pointer;" oninput="updateFromSlider(this.value)">
|
||||
<div style="display: flex; justify-content: space-between; font-size: 11px; color: var(--text-secondary); margin-top: 8px; font-weight: 500;">
|
||||
<span onclick="setSlider(0)" style="cursor: pointer;">0%</span><span onclick="setSlider(25)" style="cursor: pointer;">25%</span><span onclick="setSlider(50)" style="cursor: pointer;">50%</span><span onclick="setSlider(75)" style="cursor: pointer;">75%</span><span onclick="setSlider(100)" style="cursor: pointer;">100%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size: 13px; display: flex; justify-content: space-between; margin-top: 15px;">
|
||||
<span style="color: var(--text-secondary);">预计保证金</span>
|
||||
<span><span id="order-cost">0.00</span> USDT</span>
|
||||
<div style="font-size: 14px; display: flex; justify-content: space-between; margin-top: 15px;">
|
||||
<span style="color: var(--text-secondary); font-weight: 600;"><?php echo __('margin'); ?></span>
|
||||
<span style="font-weight: 700;"><span id="order-cost">0.00</span> USDT</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-top: 20px;">
|
||||
<button class="btn-trade" style="background: var(--up-color);" onclick="placeOrder('buy')">开多 (买入)</button>
|
||||
<button class="btn-trade" style="background: var(--down-color);" onclick="placeOrder('sell')">开空 (卖出)</button>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 25px;">
|
||||
<button class="btn-trade" style="background: var(--up-color);" onclick="placeOrder('buy')"><?php echo __('open_long'); ?></button>
|
||||
<button class="btn-trade" style="background: var(--down-color);" onclick="placeOrder('sell')"><?php echo __('open_short'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background: var(--panel-bg);">
|
||||
<div style="display: flex; border-bottom: 1px solid var(--border-color); padding: 0 15px; overflow-x: auto;">
|
||||
<button class="tab-btn active" onclick="switchTab(this, 'positions')" style="background: none; border: none; color: var(--accent-color); padding: 12px 15px; font-size: 14px; border-bottom: 2px solid var(--accent-color); cursor: pointer; white-space: nowrap;">当前持仓</button>
|
||||
<button class="tab-btn" onclick="switchTab(this, 'open')" style="background: none; border: none; color: var(--text-secondary); padding: 12px 15px; font-size: 14px; cursor: pointer; white-space: nowrap;">当前委托</button>
|
||||
<div style="display: flex; border-bottom: 1px solid var(--border-color); padding: 0 10px; overflow-x: auto;">
|
||||
<button class="tab-btn active" onclick="switchTab(this, 'positions')"><?php echo __('positions'); ?></button>
|
||||
<button class="tab-btn" onclick="switchTab(this, 'open')"><?php echo __('open_orders'); ?></button>
|
||||
</div>
|
||||
<div style="padding: 15px; overflow-x: auto;">
|
||||
<table style="width: 100%; font-size: 11px; border-collapse: collapse; min-width: 600px;">
|
||||
<thead id="data-thead" style="color: var(--text-secondary); text-align: left;"></thead>
|
||||
<table style="width: 100%; font-size: 13px; border-collapse: collapse; min-width: 800px;">
|
||||
<thead id="data-thead" style="color: var(--text-secondary); text-align: left; background: rgba(255,255,255,0.02);"></thead>
|
||||
<tbody id="data-tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -158,21 +181,23 @@ if ($user_id) {
|
||||
|
||||
<!-- Right Panel (Order Book) -->
|
||||
<div class="panel order-book-panel">
|
||||
<div style="padding: 10px 15px; font-size: 12px; color: var(--text-secondary);">价格 / 数量</div>
|
||||
<div id="asks-list" style="display: flex; flex-direction: column-reverse;"></div>
|
||||
<div id="ob-mid-price" style="padding: 10px 0; text-align: center; font-weight: bold; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">--</div>
|
||||
<div id="bids-list"></div>
|
||||
<div class="ob-header">
|
||||
<span>Price / Amount</span>
|
||||
</div>
|
||||
<div id="asks-list" style="display: flex; flex-direction: column-reverse; flex: 1; overflow: hidden;"></div>
|
||||
<div id="ob-mid-price" style="padding: 15px 0; text-align: center; font-weight: 800; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); font-size: 18px; font-family: 'Roboto Mono', monospace; background: rgba(255,255,255,0.01);">--</div>
|
||||
<div id="bids-list" style="flex: 1; overflow: hidden;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="lev-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); display: none; align-items: center; justify-content: center; z-index: 2000;">
|
||||
<div style="background: var(--panel-bg); padding: 30px; border-radius: 12px; width: 320px; text-align: center;">
|
||||
<h3 style="margin-bottom: 20px;">调整杠杆</h3>
|
||||
<div id="lev-val-big" style="font-size: 36px; font-weight: bold; color: var(--accent-color); margin-bottom: 20px;">20x</div>
|
||||
<input type="range" min="1" max="125" value="20" id="lev-range" style="width: 100%;" oninput="document.getElementById('lev-val-big').innerText = this.value + 'x'">
|
||||
<div style="display: flex; gap: 15px; margin-top: 30px;">
|
||||
<button onclick="hideLevModal()" style="flex: 1; padding: 10px; background: #2b3139; border: none; color: white; border-radius: 6px;">取消</button>
|
||||
<button onclick="confirmLev()" style="flex: 1; padding: 10px; background: var(--accent-color); border: none; color: white; border-radius: 6px;">确认</button>
|
||||
<div id="lev-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); display: none; align-items: center; justify-content: center; z-index: 2100; backdrop-filter: blur(5px);">
|
||||
<div style="background: var(--panel-bg); padding: 40px; border-radius: 20px; width: 360px; text-align: center; border: 1px solid var(--border-color); box-shadow: 0 20px 60px rgba(0,0,0,0.5);">
|
||||
<h3 style="margin-bottom: 25px; font-size: 1.5rem; font-weight: 800;"><?php echo __('adjust_leverage'); ?></h3>
|
||||
<div id="lev-val-big" style="font-size: 48px; font-weight: 800; color: var(--accent-color); margin-bottom: 30px; font-family: 'Roboto Mono', monospace;">20x</div>
|
||||
<input type="range" min="1" max="125" value="20" id="lev-range" style="width: 100%; accent-color: var(--accent-color); cursor: pointer;" oninput="document.getElementById('lev-val-big').innerText = this.value + 'x'">
|
||||
<div style="display: flex; gap: 20px; margin-top: 40px;">
|
||||
<button onclick="hideLevModal()" style="flex: 1; padding: 12px; background: #2b3139; border: none; color: white; border-radius: 10px; font-weight: 700; cursor: pointer;"><?php echo __('cancel'); ?></button>
|
||||
<button onclick="confirmLev()" style="flex: 1; padding: 12px; background: var(--accent-color); border: none; color: white; border-radius: 10px; font-weight: 700; cursor: pointer;"><?php echo __('confirm'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -187,12 +212,16 @@ if ($user_id) {
|
||||
let orderType = 'market';
|
||||
let activeTab = 'positions';
|
||||
const faceValue = 10;
|
||||
const lang = '<?php echo $lang; ?>';
|
||||
|
||||
const pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT', 'ADAUSDT', 'DOGEUSDT', 'AVAXUSDT'];
|
||||
const pairs = [
|
||||
'BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT', 'XRPUSDT', 'ADAUSDT', 'AVAXUSDT', 'DOGEUSDT', 'DOTUSDT', 'LINKUSDT',
|
||||
'MATICUSDT', 'NEARUSDT', 'LTCUSDT', 'ATOMUSDT', 'UNIUSDT', 'XLMUSDT', 'ALGOUSDT', 'TRXUSDT', 'BCHUSDT', 'SHIBUSDT'
|
||||
];
|
||||
|
||||
function initChart(symbol) {
|
||||
new TradingView.widget({
|
||||
"width": "100%", "height": "100%", "symbol": "BINANCE:" + symbol, "interval": "15", "theme": "dark", "style": "1", "locale": "zh_CN", "container_id": "tv_chart_container", "backgroundColor": "#0b0e11", "hide_side_toolbar": true
|
||||
"width": "100%", "height": "100%", "symbol": "BINANCE:" + symbol, "interval": "15", "theme": "dark", "style": "1", "locale": lang === 'zh' ? 'zh_CN' : 'en', "container_id": "tv_chart_container", "backgroundColor": "#0b0e11", "hide_side_toolbar": true
|
||||
});
|
||||
}
|
||||
initChart(currentPair);
|
||||
@ -218,6 +247,7 @@ if ($user_id) {
|
||||
document.getElementById('mark-price').innerText = currentPrice.toLocaleString();
|
||||
document.getElementById('vol-24h').innerText = parseFloat(data.q).toLocaleString();
|
||||
document.getElementById('ob-mid-price').innerText = currentPrice.toLocaleString();
|
||||
document.getElementById('ob-mid-price').style.color = data.P >= 0 ? 'var(--up-color)' : 'var(--down-color)';
|
||||
updateOrderBook();
|
||||
}
|
||||
|
||||
@ -227,17 +257,30 @@ if ($user_id) {
|
||||
let html = '';
|
||||
pairs.forEach(p => {
|
||||
const d = marketData[p] || {c: 0, P: 0};
|
||||
html += `<div class="pair-item ${currentPair === p ? 'active' : ''}" onclick="switchPair('${p}')">
|
||||
<span>${p}/USDT</span>
|
||||
<span style="color: ${d.P >= 0 ? 'var(--up-color)' : 'var(--down-color)'}">${parseFloat(d.c).toLocaleString()}</span>
|
||||
</div>`;
|
||||
const name = p.replace('USDT', '');
|
||||
const icon = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png`;
|
||||
html += `
|
||||
<div class="pair-item ${currentPair === p ? 'active' : ''}" onclick="switchPair('${p}')">
|
||||
<img src="${icon}" class="pair-icon" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; font-size: 14px;">${name}/USDT</div>
|
||||
<div style="font-size: 11px; color: var(--text-secondary);">Vol ${parseFloat(d.q || 0).toLocaleString()}</div>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<div style="font-weight: 600; font-family: 'Roboto Mono', monospace; font-size: 13px;">${parseFloat(d.c).toLocaleString()}</div>
|
||||
<div style="color: ${d.P >= 0 ? 'var(--up-color)' : 'var(--down-color)'}; font-size: 11px; font-weight: 600;">${(d.P >= 0 ? '+' : '') + d.P}%</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
list.innerHTML = html;
|
||||
}
|
||||
|
||||
function switchPair(p) {
|
||||
if (currentPair === p) return;
|
||||
currentPair = p;
|
||||
document.getElementById('current-pair-display').innerText = p + '/USDT 永续';
|
||||
document.getElementById('current-pair-display').innerText = p + '/USDT ' + (lang === 'zh' ? '永续' : 'Perpetual');
|
||||
document.getElementById('current-logo').src = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${p.replace('USDT','').toLowerCase()}.png`;
|
||||
initChart(p);
|
||||
}
|
||||
|
||||
@ -245,13 +288,45 @@ if ($user_id) {
|
||||
const asks = document.getElementById('asks-list');
|
||||
const bids = document.getElementById('bids-list');
|
||||
let aH = ''; let bH = '';
|
||||
for(let i=0; i<10; i++) {
|
||||
aH += `<div style="display: flex; justify-content: space-between; padding: 2px 15px; font-size: 11px;"><span style="color: var(--down-color);">${(currentPrice*(1+(i+1)*0.0005)).toFixed(1)}</span><span>${(Math.random()*100).toFixed(0)}</span></div>`;
|
||||
bH += `<div style="display: flex; justify-content: space-between; padding: 2px 15px; font-size: 11px;"><span style="color: var(--up-color);">${(currentPrice*(1-(i+1)*0.0005)).toFixed(1)}</span><span>${(Math.random()*100).toFixed(0)}</span></div>`;
|
||||
let maxVol = 0;
|
||||
const rows = 18;
|
||||
const askData = [];
|
||||
const bidData = [];
|
||||
|
||||
for(let i=0; i<rows; i++) {
|
||||
const av = Math.random() * 200 + 10;
|
||||
const bv = Math.random() * 200 + 10;
|
||||
askData.push(av);
|
||||
bidData.push(bv);
|
||||
maxVol = Math.max(maxVol, av, bv);
|
||||
}
|
||||
|
||||
for(let i=0; i<rows; i++) {
|
||||
const ap = currentPrice * (1 + (i + 1) * 0.0003);
|
||||
const bp = currentPrice * (1 - (i + 1) * 0.0003);
|
||||
const av = askData[i];
|
||||
const bv = bidData[i];
|
||||
|
||||
aH += `
|
||||
<div class="ob-row" onclick="setPrice(${ap.toFixed(1)})">
|
||||
<div class="ob-vol-bar" style="width: ${(av/maxVol*100)}%; background: var(--down-color);"></div>
|
||||
<span style="color: var(--down-color); font-weight: 600; z-index: 1;">${ap.toFixed(1)}</span>
|
||||
<span style="color: white; opacity: 0.9; z-index: 1;">${av.toFixed(0)}</span>
|
||||
</div>`;
|
||||
bH += `
|
||||
<div class="ob-row" onclick="setPrice(${bp.toFixed(1)})">
|
||||
<div class="ob-vol-bar" style="width: ${(bv/maxVol*100)}%; background: var(--up-color);"></div>
|
||||
<span style="color: var(--up-color); font-weight: 600; z-index: 1;">${bp.toFixed(1)}</span>
|
||||
<span style="color: white; opacity: 0.9; z-index: 1;">${bv.toFixed(0)}</span>
|
||||
</div>`;
|
||||
}
|
||||
asks.innerHTML = aH; bids.innerHTML = bH;
|
||||
}
|
||||
|
||||
function setPrice(p) {
|
||||
if (orderType === 'limit') document.getElementById('order-price').value = p;
|
||||
}
|
||||
|
||||
function setSlider(val) { document.getElementById('order-slider').value = val; updateFromSlider(val); }
|
||||
function updateFromSlider(val) {
|
||||
const cost = usdtBalance * (val / 100);
|
||||
@ -264,8 +339,10 @@ if ($user_id) {
|
||||
function confirmLev() {
|
||||
leverage = document.getElementById('lev-range').value;
|
||||
document.getElementById('leverage-display').innerText = leverage + 'x';
|
||||
document.getElementById('leverage-val-info').innerText = leverage;
|
||||
document.getElementById('leverage-val').innerText = leverage;
|
||||
hideLevModal();
|
||||
updateFromSlider(document.getElementById('order-slider').value);
|
||||
}
|
||||
|
||||
function setOrderType(type) {
|
||||
@ -277,7 +354,7 @@ if ($user_id) {
|
||||
|
||||
async function placeOrder(side) {
|
||||
const amount = parseFloat(document.getElementById('order-amount').value);
|
||||
if (!amount) return alert('数量错误');
|
||||
if (!amount || amount <= 0) return alert(lang === 'zh' ? '请输入有效数量' : 'Please enter a valid amount');
|
||||
const price = orderType === 'limit' ? parseFloat(document.getElementById('order-price').value) : currentPrice;
|
||||
const resp = await fetch('api/place_order.php', {
|
||||
method: 'POST',
|
||||
@ -288,7 +365,10 @@ if ($user_id) {
|
||||
})
|
||||
});
|
||||
const res = await resp.json();
|
||||
if (res.success) { alert('成功'); fetchOrders(); } else { alert(res.error); }
|
||||
if (res.success) {
|
||||
alert(lang === 'zh' ? '下单成功' : 'Order Placed Successfully');
|
||||
fetchOrders();
|
||||
} else { alert(res.error); }
|
||||
}
|
||||
|
||||
async function fetchOrders() {
|
||||
@ -297,30 +377,48 @@ if ($user_id) {
|
||||
const tbody = document.getElementById('data-tbody');
|
||||
const thead = document.getElementById('data-thead');
|
||||
if (activeTab === 'positions') {
|
||||
thead.innerHTML = `<tr><th style="padding: 10px 5px;">合约</th><th style="padding: 10px 5px;">仓位</th><th style="padding: 10px 5px;">开仓价</th><th style="padding: 10px 5px;">盈亏</th><th style="padding: 10px 5px; text-align: right;">操作</th></tr>`;
|
||||
thead.innerHTML = `<tr><th style="padding: 12px 10px;"><?php echo __('pair'); ?></th><th style="padding: 12px 10px;"><?php echo __('direction'); ?></th><th style="padding: 12px 10px;"><?php echo __('price'); ?></th><th style="padding: 12px 10px;"><?php echo __('pnl'); ?></th><th style="padding: 12px 10px; text-align: right;"><?php echo __('action'); ?></th></tr>`;
|
||||
} else {
|
||||
thead.innerHTML = `<tr><th style="padding: 10px 5px;">时间</th><th style="padding: 10px 5px;">合约</th><th style="padding: 10px 5px;">方向</th><th style="padding: 10px 5px;">价格</th><th style="padding: 10px 5px;">数量</th><th style="padding: 10px 5px; text-align: right;">操作</th></tr>`;
|
||||
thead.innerHTML = `<tr><th style="padding: 12px 10px;"><?php echo __('time'); ?></th><th style="padding: 12px 10px;"><?php echo __('pair'); ?></th><th style="padding: 12px 10px;"><?php echo __('direction'); ?></th><th style="padding: 12px 10px;"><?php echo __('price'); ?></th><th style="padding: 12px 10px;"><?php echo __('amount'); ?></th><th style="padding: 12px 10px; text-align: right;"><?php echo __('action'); ?></th></tr>`;
|
||||
}
|
||||
if (res.success && res.data.length > 0) {
|
||||
tbody.innerHTML = res.data.map(o => {
|
||||
const color = o.side === 'buy' ? 'var(--up-color)' : 'var(--down-color)';
|
||||
return `<tr style="border-bottom: 1px solid var(--border-color);">
|
||||
<td style="padding: 10px 5px;">${o.symbol}</td>
|
||||
<td style="padding: 10px 5px; color: ${color};">${o.side === 'buy' ? '多' : '空'} ${o.leverage}x</td>
|
||||
<td style="padding: 10px 5px;">${parseFloat(o.price).toLocaleString()}</td>
|
||||
<td style="padding: 10px 5px;">--</td>
|
||||
<td style="padding: 10px 5px; text-align: right;"><button onclick="closePos(${o.id})">平仓</button></td>
|
||||
</tr>`;
|
||||
if (activeTab === 'positions') {
|
||||
return `<tr style="border-bottom: 1px solid var(--border-color);">
|
||||
<td style="padding: 15px 10px; font-weight: 700;">${o.symbol}</td>
|
||||
<td style="padding: 15px 10px; color: ${color}; font-weight: 700;">${o.side === 'buy' ? (lang === 'zh' ? '多' : 'LONG') : (lang === 'zh' ? '空' : 'SHORT')} ${o.leverage}x</td>
|
||||
<td style="padding: 15px 10px; font-family: 'Roboto Mono', monospace;">${parseFloat(o.price).toLocaleString()}</td>
|
||||
<td style="padding: 15px 10px; font-weight: 700;">--</td>
|
||||
<td style="padding: 15px 10px; text-align: right;"><button onclick="closePos(${o.id})" style="background: rgba(255,255,255,0.05); color: white; border: 1px solid var(--border-color); padding: 5px 15px; border-radius: 6px; cursor: pointer; font-size: 12px;"><?php echo __('close_position'); ?></button></td>
|
||||
</tr>`;
|
||||
} else {
|
||||
return `<tr style="border-bottom: 1px solid var(--border-color);">
|
||||
<td style="padding: 15px 10px;">${o.created_at}</td>
|
||||
<td style="padding: 15px 10px; font-weight: 700;">${o.symbol}</td>
|
||||
<td style="padding: 15px 10px; color: ${color}; font-weight: 700;">${o.side.toUpperCase()}</td>
|
||||
<td style="padding: 15px 10px; font-family: 'Roboto Mono', monospace;">${parseFloat(o.price).toLocaleString()}</td>
|
||||
<td style="padding: 15px 10px;">${o.amount}</td>
|
||||
<td style="padding: 15px 10px; text-align: right;"><button onclick="cancelOrder(${o.id})" style="background: var(--danger-color); color: white; border: none; padding: 5px 15px; border-radius: 6px; cursor: pointer; font-size: 12px;"><?php echo __('cancel'); ?></button></td>
|
||||
</tr>`;
|
||||
}
|
||||
}).join('');
|
||||
} else { tbody.innerHTML = '<tr><td colspan="5" style="text-align: center; padding: 40px;">暂无记录</td></tr>'; }
|
||||
} else { tbody.innerHTML = `<tr><td colspan="5" style="text-align: center; padding: 60px; color: var(--text-secondary);"><?php echo __('no_records'); ?></td></tr>`; }
|
||||
}
|
||||
|
||||
function switchTab(btn, tab) {
|
||||
document.querySelectorAll('.tab-btn').forEach(b => { b.classList.remove('active'); b.style.color = 'var(--text-secondary)'; b.style.borderBottom = 'none'; });
|
||||
btn.classList.add('active'); btn.style.color = 'var(--accent-color)'; btn.style.borderBottom = '2px solid var(--accent-color)';
|
||||
activeTab = tab; fetchOrders();
|
||||
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active'); activeTab = tab; fetchOrders();
|
||||
}
|
||||
|
||||
document.getElementById('market-search').addEventListener('input', function(e) {
|
||||
const q = e.target.value.toUpperCase();
|
||||
document.querySelectorAll('.pair-item').forEach(item => {
|
||||
const text = item.querySelector('div div').innerText;
|
||||
item.style.display = text.includes(q) ? 'flex' : 'none';
|
||||
});
|
||||
});
|
||||
|
||||
fetchOrders(); setInterval(fetchOrders, 4000);
|
||||
</script>
|
||||
|
||||
|
||||
124
header.php
124
header.php
@ -1,16 +1,28 @@
|
||||
<?php require_once 'includes/i18n.php'; ?>
|
||||
<?php
|
||||
require_once 'includes/i18n.php';
|
||||
require_once 'db/config.php';
|
||||
$db = db();
|
||||
$settings_res = $db->query("SELECT * FROM settings")->fetchAll();
|
||||
$settings = [];
|
||||
foreach($settings_res as $s) $settings[$s['name']] = $s['value'];
|
||||
$site_logo = $settings['site_logo'] ?? null;
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo $lang; ?>">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>NovaEx | Leading Crypto Exchange</title>
|
||||
<?php if($site_logo): ?>
|
||||
<link rel="icon" href="<?php echo $site_logo; ?>" type="image/x-icon">
|
||||
<?php endif; ?>
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<style>
|
||||
.logo-text { font-size: 1.8rem; font-weight: 800; color: white; letter-spacing: -1px; display: flex; align-items: center; gap: 8px; font-family: 'Inter', sans-serif; }
|
||||
.logo-svg { width: 32px; height: 32px; fill: #4facfe; }
|
||||
.site-logo-img { max-height: 40px; width: auto; object-fit: contain; }
|
||||
|
||||
/* Floating CS Chat */
|
||||
.floating-service { position: fixed; bottom: 85px; right: 20px; width: 50px; height: 50px; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 1.2rem; cursor: pointer; box-shadow: 0 10px 25px rgba(0,242,254,0.3); z-index: 999; transition: transform 0.3s ease; }
|
||||
@ -27,6 +39,15 @@
|
||||
/* Mobile Sidebar Links */
|
||||
.sidebar-links a { display: flex; align-items: center; gap: 15px; padding: 15px 10px; color: white; text-decoration: none; border-bottom: 1px solid rgba(255,255,255,0.05); font-size: 1.1rem; }
|
||||
.sidebar-links a i { width: 25px; text-align: center; }
|
||||
|
||||
/* Language and CSS helper classes */
|
||||
.desktop-only { display: flex !important; }
|
||||
@media (max-width: 992px) {
|
||||
.desktop-only { display: none !important; }
|
||||
.navbar { padding: 10px 15px !important; }
|
||||
.logo-name { font-size: 1.2rem; }
|
||||
#mobileMenuBtn { display: block !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -36,8 +57,14 @@
|
||||
|
||||
<!-- Mobile Sidebar -->
|
||||
<div class="mobile-sidebar" id="mobileSidebar">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px;">
|
||||
<div class="logo-text" style="font-size: 1.5rem;">NovaEx</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; padding: 0 10px;">
|
||||
<div class="logo-text">
|
||||
<?php if($site_logo): ?>
|
||||
<img src="<?php echo $site_logo; ?>" class="site-logo-img" alt="Logo">
|
||||
<?php else: ?>
|
||||
<span style="font-size: 1.5rem;">NovaEx</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<i class="fas fa-times" style="font-size: 1.5rem; cursor: pointer;" onclick="toggleSidebar()"></i>
|
||||
</div>
|
||||
|
||||
@ -47,15 +74,18 @@
|
||||
<a href="options.php"><i class="fas fa-clock" style="color: #fbc02d;"></i> <?php echo __('nav_options'); ?></a>
|
||||
<a href="spot.php"><i class="fas fa-coins" style="color: #ffd600;"></i> <?php echo __('nav_spot'); ?></a>
|
||||
<a href="futures.php"><i class="fas fa-file-contract" style="color: #ff3d00;"></i> <?php echo __('nav_futures'); ?></a>
|
||||
<a href="convert.php"><i class="fas fa-bolt" style="color: #fbc02d;"></i> <?php echo __('nav_convert'); ?></a>
|
||||
<a href="mining.php"><i class="fas fa-pickaxe" style="color: #8e24aa;"></i> <?php echo __('nav_mining'); ?></a>
|
||||
<a href="app.php"><i class="fas fa-mobile-alt" style="color: #4facfe;"></i> <?php echo __('nav_app_download', 'APP Download'); ?></a>
|
||||
<a href="app.php"><i class="fas fa-mobile-alt" style="color: #4facfe;"></i> <?php echo __('nav_app_download'); ?></a>
|
||||
<hr style="border: none; border-top: 1px solid rgba(255,255,255,0.1); margin: 15px 0;">
|
||||
<div style="padding: 10px;">
|
||||
<div style="color: var(--text-muted); font-size: 12px; margin-bottom: 15px;"><?php echo __('language', 'Language'); ?></div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="?lang=en" style="padding: 8px 15px; background: #1e2329; border-radius: 6px; font-size: 14px; flex: 1; border: none; justify-content: center;">English</a>
|
||||
<a href="?lang=zh" style="padding: 8px 15px; background: #1e2329; border-radius: 6px; font-size: 14px; flex: 1; border: none; justify-content: center;">简体中文</a>
|
||||
<a href="?lang=en" style="padding: 12px; background: #1e2329; border-radius: 8px; font-size: 14px; flex: 1; border: none; justify-content: center; text-decoration: none; color: white; display: flex; align-items: center; gap: 8px;">
|
||||
<img src="https://flagcdn.com/w20/us.png" width="20" alt="English"> EN
|
||||
</a>
|
||||
<a href="?lang=zh" style="padding: 12px; background: #1e2329; border-radius: 8px; font-size: 14px; flex: 1; border: none; justify-content: center; text-decoration: none; color: white; display: flex; align-items: center; gap: 8px;">
|
||||
<img src="https://flagcdn.com/w20/cn.png" width="20" alt="Chinese"> 中文
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -74,47 +104,51 @@
|
||||
</div>
|
||||
|
||||
<nav class="navbar">
|
||||
<div style="display: flex; align-items: center; gap: 1rem;">
|
||||
<div style="display: flex; align-items: center; gap: 1.5rem;">
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<i class="fas fa-bars" id="mobileMenuBtn" style="font-size: 1.2rem; cursor: pointer; display: none;" onclick="toggleSidebar()"></i>
|
||||
|
||||
<a href="index.php" style="text-decoration: none;">
|
||||
<div class="logo-text">
|
||||
<svg class="logo-svg" viewBox="0 0 100 100">
|
||||
<rect x="10" y="10" width="80" height="80" rx="20" fill="url(#grad1)"/>
|
||||
<path d="M30 30 L70 70 M70 30 L30 70" stroke="white" stroke-width="12" stroke-linecap="round"/>
|
||||
<defs>
|
||||
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#4facfe;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#00f2fe;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<span class="logo-name">NovaEx</span>
|
||||
<?php if($site_logo): ?>
|
||||
<img src="<?php echo $site_logo; ?>" class="site-logo-img" alt="Logo">
|
||||
<?php else: ?>
|
||||
<svg class="logo-svg" viewBox="0 0 100 100">
|
||||
<rect x="10" y="10" width="80" height="80" rx="20" fill="url(#grad1)"/>
|
||||
<path d="M30 30 L70 70 M70 30 L30 70" stroke="white" stroke-width="12" stroke-linecap="round"/>
|
||||
<defs>
|
||||
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#4facfe;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#00f2fe;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<span class="logo-name">NovaEx</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
<div class="nav-links">
|
||||
<div class="nav-links desktop-only">
|
||||
<a href="index.php"><?php echo __('nav_home'); ?></a>
|
||||
<a href="markets.php"><?php echo __('nav_market'); ?></a>
|
||||
<a href="options.php"><?php echo __('nav_options'); ?></a>
|
||||
<a href="spot.php"><?php echo __('nav_spot'); ?></a>
|
||||
<a href="futures.php"><?php echo __('nav_futures'); ?></a>
|
||||
<a href="mining.php"><?php echo __('nav_mining'); ?></a>
|
||||
<a href="profile.php"><?php echo __('nav_assets'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 1rem; align-items: center;">
|
||||
<div class="dropdown desktop-only">
|
||||
<a href="#" style="color: white; display: flex; align-items: center; gap: 5px;">
|
||||
<i class="fas fa-globe"></i>
|
||||
<span style="font-size: 13px;"><?php echo strtoupper($lang); ?></span>
|
||||
<a href="#" style="color: white; display: flex; align-items: center; gap: 8px; text-decoration: none; font-size: 14px; font-weight: 500;">
|
||||
<i class="fas fa-globe" style="color: var(--primary-color);"></i>
|
||||
<span><?php echo $lang == 'en' ? 'English' : '简体中文'; ?></span>
|
||||
<i class="fas fa-chevron-down" style="font-size: 10px; opacity: 0.6;"></i>
|
||||
</a>
|
||||
<div class="dropdown-content" style="right: 0; min-width: 120px;">
|
||||
<a href="?lang=en" style="display: flex; align-items: center; gap: 10px;">
|
||||
<div class="dropdown-content" style="right: 0; min-width: 150px; border-radius: 12px; overflow: hidden; border: 1px solid var(--border-color); box-shadow: 0 10px 30px rgba(0,0,0,0.3);">
|
||||
<a href="?lang=en" style="display: flex; align-items: center; gap: 12px; padding: 12px 15px;">
|
||||
<img src="https://flagcdn.com/w20/us.png" width="20" alt="English"> English
|
||||
</a>
|
||||
<a href="?lang=zh" style="display: flex; align-items: center; gap: 10px;">
|
||||
<a href="?lang=zh" style="display: flex; align-items: center; gap: 12px; padding: 12px 15px;">
|
||||
<img src="https://flagcdn.com/w20/cn.png" width="20" alt="Chinese"> 简体中文
|
||||
</a>
|
||||
</div>
|
||||
@ -122,24 +156,24 @@
|
||||
|
||||
<?php if(isset($_SESSION['user_id'])): ?>
|
||||
<div class="dropdown">
|
||||
<a href="#" style="color: white; display: flex; align-items: center; gap: 8px;">
|
||||
<i class="fas fa-user-circle" style="font-size: 1.5rem;"></i>
|
||||
<i class="fas fa-chevron-down desktop-only" style="font-size: 10px;"></i>
|
||||
<a href="#" style="color: white; display: flex; align-items: center; gap: 8px; text-decoration: none;">
|
||||
<i class="fas fa-user-circle" style="font-size: 1.8rem; color: var(--primary-color);"></i>
|
||||
<i class="fas fa-chevron-down desktop-only" style="font-size: 10px; opacity: 0.6;"></i>
|
||||
</a>
|
||||
<div class="dropdown-content user-profile-dropdown" style="right: 0;">
|
||||
<div class="user-info-header">
|
||||
<div style="font-weight: bold; margin-bottom: 4px;"><?php echo $_SESSION['username'] ?? 'User'; ?></div>
|
||||
<div class="uid-badge">UID: <?php echo $_SESSION['uid'] ?? '------'; ?></div>
|
||||
<div class="dropdown-content user-profile-dropdown" style="right: 0; border-radius: 12px; overflow: hidden; border: 1px solid var(--border-color);">
|
||||
<div class="user-info-header" style="background: rgba(79, 172, 254, 0.1); padding: 15px;">
|
||||
<div style="font-weight: bold; margin-bottom: 4px; color: white;"><?php echo $_SESSION['username'] ?? 'User'; ?></div>
|
||||
<div class="uid-badge" style="background: rgba(255,255,255,0.1); padding: 2px 8px; border-radius: 4px; font-size: 11px;">UID: <?php echo $_SESSION['uid'] ?? '------'; ?></div>
|
||||
</div>
|
||||
<a href="profile.php"><i class="fas fa-wallet" style="color: #03a9f4;"></i> <?php echo __('nav_assets'); ?></a>
|
||||
<a href="deposit.php"><i class="fas fa-plus-circle" style="color: #00f2fe;"></i> <?php echo __('nav_deposit'); ?></a>
|
||||
<a href="security.php"><i class="fas fa-shield-alt" style="color: #ffd600;"></i> <?php echo __('nav_security', 'Security'); ?></a>
|
||||
<a href="logout.php" style="color: var(--danger-color); border-top: 1px solid rgba(255,255,255,0.05);"><i class="fas fa-sign-out-alt"></i> <?php echo __('nav_logout'); ?></a>
|
||||
<a href="profile.php"><i class="fas fa-wallet" style="color: #03a9f4; width: 20px;"></i> <?php echo __('nav_assets'); ?></a>
|
||||
<a href="deposit.php"><i class="fas fa-plus-circle" style="color: #00f2fe; width: 20px;"></i> <?php echo __('nav_deposit'); ?></a>
|
||||
<a href="security.php"><i class="fas fa-shield-alt" style="color: #ffd600; width: 20px;"></i> <?php echo __('nav_security'); ?></a>
|
||||
<a href="logout.php" style="color: var(--danger-color); border-top: 1px solid rgba(255,255,255,0.05);"><i class="fas fa-sign-out-alt" style="width: 20px;"></i> <?php echo __('nav_logout'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<a href="login.php" class="desktop-only" style="color: white; text-decoration: none; font-size: 14px;"><?php echo __('nav_login'); ?></a>
|
||||
<a href="register.php" class="btn-primary" style="padding: 6px 15px; font-size: 13px;"><?php echo __('nav_register'); ?></a>
|
||||
<a href="login.php" class="desktop-only" style="color: white; text-decoration: none; font-size: 14px; font-weight: 500;"><?php echo __('nav_login'); ?></a>
|
||||
<a href="register.php" class="btn-primary" style="padding: 8px 20px; font-size: 14px; border-radius: 8px; font-weight: 600;"><?php echo __('nav_register'); ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</nav>
|
||||
@ -156,7 +190,7 @@
|
||||
</a>
|
||||
<a href="options.php" class="mobile-nav-item <?php echo in_array(basename($_SERVER['PHP_SELF']), ['options.php', 'spot.php', 'futures.php']) ? 'active' : ''; ?>">
|
||||
<i class="fas fa-exchange-alt"></i>
|
||||
<span><?php echo __('nav_trade', 'Trade'); ?></span>
|
||||
<span><?php echo __('nav_trade'); ?></span>
|
||||
</a>
|
||||
<a href="mining.php" class="mobile-nav-item <?php echo basename($_SERVER['PHP_SELF']) == 'mining.php' ? 'active' : ''; ?>">
|
||||
<i class="fas fa-pickaxe"></i>
|
||||
@ -168,14 +202,6 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@media (max-width: 992px) {
|
||||
#mobileMenuBtn { display: block !important; }
|
||||
.desktop-only { display: none !important; }
|
||||
.logo-name { font-size: 1.4rem; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function toggleSidebar() {
|
||||
const sidebar = document.getElementById('mobileSidebar');
|
||||
|
||||
@ -8,6 +8,7 @@ $translations = [
|
||||
'nav_trade' => 'Trade',
|
||||
'nav_spot' => 'Spot',
|
||||
'nav_futures' => 'Futures',
|
||||
'nav_options' => 'Second Contract',
|
||||
'nav_mining' => 'Mining',
|
||||
'nav_convert' => 'Convert',
|
||||
'nav_assets' => 'Assets',
|
||||
@ -18,24 +19,38 @@ $translations = [
|
||||
'nav_register' => 'Sign Up',
|
||||
'nav_profile' => 'Profile',
|
||||
'nav_logout' => 'Log Out',
|
||||
'nav_security' => 'Security',
|
||||
'nav_app_download' => 'APP Download',
|
||||
|
||||
'hero_title' => 'Buy, trade, and hold 350+ cryptocurrencies on NovaEx',
|
||||
'hero_subtitle' => 'Join the world\'s largest crypto exchange with the lowest fees and best security.',
|
||||
'btn_start' => 'Get Started',
|
||||
'btn_download' => 'Download App',
|
||||
'app_download' => 'APP Download',
|
||||
'download_qr_tip' => 'Download App & Get Up to 50 USDT',
|
||||
'join_now' => 'Join Now',
|
||||
'start_trading' => 'Start Trading',
|
||||
'earn_now' => 'Earn Now',
|
||||
|
||||
'market_trends' => 'Market Trends',
|
||||
'view_more_markets' => 'View More Markets',
|
||||
'why_choose_us' => 'Why Choose Us?',
|
||||
'view_more_markets' => 'View More',
|
||||
'pair' => 'Pair',
|
||||
'last_price' => 'Last Price',
|
||||
'24h_change' => '24h Change',
|
||||
'market_cap' => 'Market Cap',
|
||||
|
||||
'why_choose_us' => 'Why Choose NovaEx?',
|
||||
'secure_storage' => 'Secure Storage',
|
||||
'secure_storage_desc' => 'We store the vast majority of the digital assets in secure offline storage.',
|
||||
'protected_insurance' => 'Protected by Insurance',
|
||||
'protected_insurance_desc' => 'Cryptocurrency stored on our servers is covered by our insurance policy.',
|
||||
'industry_best_practices' => 'Industry Best Practices',
|
||||
'industry_best_practices' => 'Best Practices',
|
||||
'industry_best_practices_desc' => 'NovaEx supports a variety of the most popular digital currencies.',
|
||||
'platform_desc' => 'Our platform provides a seamless trading experience with advanced features and a robust infrastructure designed for both retail and institutional traders.',
|
||||
'partners' => 'Our Partners',
|
||||
|
||||
'global_partners' => 'Global Partners',
|
||||
'partners_subtitle' => 'Trusted by world-leading organizations and financial institutions.',
|
||||
|
||||
'footer_desc' => 'NovaEx is a leading digital asset trading platform, providing secure and stable trading services for global users.',
|
||||
'about' => 'About',
|
||||
'about_us' => 'About Us',
|
||||
@ -59,110 +74,57 @@ $translations = [
|
||||
'cookie_policy' => 'Cookie Policy',
|
||||
'security' => 'Security',
|
||||
'system_status_normal' => 'System Status: Normal',
|
||||
'personal_center' => 'Personal Center',
|
||||
'uid' => 'UID',
|
||||
'credit_score' => 'Credit Score',
|
||||
'kyc_status' => 'Identity Verification',
|
||||
'kyc_none' => 'Not Verified',
|
||||
'kyc_pending' => 'Pending Review',
|
||||
'kyc_approved' => 'Verified',
|
||||
'kyc_rejected' => 'Verification Failed',
|
||||
'kyc_submit' => 'Submit Verification',
|
||||
'total_balance' => 'Total Balance',
|
||||
'available_balance' => 'Available',
|
||||
'order_book' => 'Order Book',
|
||||
'trade_panel' => 'Trade Panel',
|
||||
'k_line' => 'K-Line',
|
||||
'open_orders' => 'Open Orders',
|
||||
'order_history' => 'Order History',
|
||||
'trade_history' => 'Trade History',
|
||||
'funds_flow' => 'Funds Flow',
|
||||
'current_positions' => 'Current Positions',
|
||||
'limit' => 'Limit',
|
||||
'market' => 'Market',
|
||||
|
||||
'search_pair' => 'Search Pairs',
|
||||
'search_contract' => 'Search Contracts',
|
||||
'price' => 'Price',
|
||||
'amount' => 'Amount',
|
||||
'total' => 'Total',
|
||||
'available' => 'Available',
|
||||
'limit' => 'Limit',
|
||||
'market' => 'Market',
|
||||
'buy' => 'Buy',
|
||||
'sell' => 'Sell',
|
||||
'leverage' => 'Leverage',
|
||||
'tp_sl' => 'TP/SL',
|
||||
'take_profit' => 'Take Profit',
|
||||
'stop_loss' => 'Stop Loss',
|
||||
'cost' => 'Cost',
|
||||
'buy_long' => 'Buy Long',
|
||||
'sell_short' => 'Sell Short',
|
||||
'open_long' => 'Open Long',
|
||||
'open_short' => 'Open Short',
|
||||
'security_settings' => 'Security Settings',
|
||||
'asset_details' => 'Asset Details',
|
||||
'transaction_records' => 'Transaction Records',
|
||||
'level' => 'Level',
|
||||
'crypto_markets' => 'Crypto Markets',
|
||||
'24h_volume' => '24h Volume',
|
||||
'fear_greed' => 'Fear & Greed Index',
|
||||
'btc_dominance' => 'BTC Dominance',
|
||||
'favorites' => 'Favorites',
|
||||
'all_crypto' => 'All Crypto',
|
||||
'asset' => 'Asset',
|
||||
'24h_high_low' => '24h High/Low',
|
||||
'deposit_assets' => 'Deposit Assets',
|
||||
'deposit_method_tip' => 'Select your preferred method to fund your account.',
|
||||
'fiat_deposit' => 'Fiat Deposit',
|
||||
'crypto_deposit' => 'Crypto Deposit',
|
||||
'bank_transfer' => 'Local Bank Transfer',
|
||||
'blockchain_transfer' => 'Blockchain Transfer',
|
||||
'support_20_global' => 'Support 20+ Global Currencies',
|
||||
'safe_compliant' => 'Safe & Compliant Channel',
|
||||
'fast_processing' => '24/7 Fast Processing',
|
||||
'no_service_fee' => 'No Service Fee',
|
||||
'select_currency' => 'Select Currency',
|
||||
'deposit_amount' => 'Deposit Amount',
|
||||
'matching_instructions' => 'Matching Instructions',
|
||||
'matching_tip' => 'Our intelligent matching system will pair you with a verified merchant. After confirming, you will receive the bank account details. Please complete the transfer within the time limit.',
|
||||
'match_now' => 'Match Merchant Now',
|
||||
'select_network' => 'Select Network',
|
||||
'get_address' => 'Get Deposit Address',
|
||||
'withdraw_assets' => 'Withdraw Assets',
|
||||
'withdraw_tip' => 'Securely withdraw USDT to your external wallet.',
|
||||
'withdraw_address' => 'Withdrawal Address',
|
||||
'trading_password' => 'Trading Password',
|
||||
'submit_withdrawal' => 'Submit Withdrawal',
|
||||
'withdrawal_tips' => 'Withdrawal Tips',
|
||||
'withdrawal_tip_1' => 'Double check the destination address. We cannot recover funds sent to wrong addresses.',
|
||||
'withdrawal_tip_2' => 'TRC20 withdrawals usually take 5-10 minutes to arrive.',
|
||||
'withdrawal_tip_3' => 'Withdrawals are processed manually for security audits during peak hours.',
|
||||
'withdrawal_tip_4' => 'Handling fee: 1 USDT per transaction.',
|
||||
'recent_history' => 'Recent History',
|
||||
'no_records' => 'No records found',
|
||||
'max' => 'MAX',
|
||||
'customer_service' => 'Online Support',
|
||||
'chat_welcome' => 'Hello! How can we help you today?',
|
||||
'type_message' => 'Type your message...',
|
||||
'matching_account' => 'Matching Payment Account...',
|
||||
'matching_desc' => 'Our system is matching a secure local account for your deposit. Please wait a moment.',
|
||||
'crypto' => 'Cryptocurrency',
|
||||
'search_market' => 'Search Market',
|
||||
'more_pairs' => 'More Pairs',
|
||||
'limit_order' => 'Limit',
|
||||
'market_order' => 'Market',
|
||||
'available' => 'Available',
|
||||
'buy_long' => 'Buy / Long',
|
||||
'sell_short' => 'Sell / Short',
|
||||
'open_position' => 'Open',
|
||||
'close_position' => 'Close',
|
||||
'cross' => 'Cross',
|
||||
'leverage' => 'Leverage',
|
||||
'margin' => 'Margin',
|
||||
'isolated' => 'Isolated',
|
||||
'cross' => 'Cross',
|
||||
'order_book' => 'Order Book',
|
||||
'open_orders' => 'Open Orders',
|
||||
'order_history' => 'Order History',
|
||||
'positions' => 'Positions',
|
||||
'no_positions' => 'No positions found',
|
||||
'perpetual' => 'Perpetual',
|
||||
'delivery' => 'Delivery',
|
||||
'fee' => 'Fee',
|
||||
'max_open' => 'Max Open',
|
||||
'no_records' => 'No Records',
|
||||
'cancel' => 'Cancel',
|
||||
'confirm' => 'Confirm',
|
||||
'adjust_leverage' => 'Adjust Leverage',
|
||||
'close_position' => 'Close',
|
||||
'time' => 'Time',
|
||||
'pair' => 'Pair',
|
||||
'side' => 'Side',
|
||||
'filled' => 'Filled',
|
||||
'status' => 'Status',
|
||||
'load_more' => 'Load More',
|
||||
'action' => 'Action',
|
||||
'type' => 'Type',
|
||||
'direction' => 'Side',
|
||||
'filled' => 'Filled',
|
||||
|
||||
'settlement_time' => 'Settlement Time',
|
||||
'buy_amount' => 'Order Amount',
|
||||
'min_order' => 'Min Order',
|
||||
'buy_up' => 'Buy Up',
|
||||
'buy_down' => 'Buy Down',
|
||||
'profit' => 'Profit',
|
||||
'expected_profit' => 'Expected Profit',
|
||||
'in_progress' => 'In Progress',
|
||||
'settled' => 'Settled',
|
||||
'opening_price' => 'Opening Price',
|
||||
'closing_price' => 'Closing Price',
|
||||
'countdown' => 'Countdown',
|
||||
'pnl' => 'P/L',
|
||||
'trading_executing' => 'Trading Executing',
|
||||
'waiting_settlement' => 'Waiting for Settlement',
|
||||
'system_matching_engine' => 'System matching engine',
|
||||
],
|
||||
'zh' => [
|
||||
'nav_home' => '首页',
|
||||
@ -170,6 +132,7 @@ $translations = [
|
||||
'nav_trade' => '交易',
|
||||
'nav_spot' => '现货交易',
|
||||
'nav_futures' => '合约交易',
|
||||
'nav_options' => '秒合约',
|
||||
'nav_mining' => '挖矿',
|
||||
'nav_convert' => '闪兑',
|
||||
'nav_assets' => '资产',
|
||||
@ -180,15 +143,27 @@ $translations = [
|
||||
'nav_register' => '注册',
|
||||
'nav_profile' => '个人中心',
|
||||
'nav_logout' => '退出登录',
|
||||
'nav_security' => '安全中心',
|
||||
'nav_app_download' => 'APP 下载',
|
||||
|
||||
'hero_title' => '在 NovaEx 购买、交易和持有 350 多种加密货币',
|
||||
'hero_subtitle' => '加入全球最大的加密货币交易所,享受最低的费用和最好的安全性。',
|
||||
'btn_start' => '立即开始',
|
||||
'btn_download' => '下载应用',
|
||||
'app_download' => 'APP 下载',
|
||||
'download_qr_tip' => '下载应用并获得高达 50 USDT 的奖励',
|
||||
'join_now' => '立即加入',
|
||||
'start_trading' => '开始交易',
|
||||
'earn_now' => '立即赚取',
|
||||
|
||||
'market_trends' => '市场趋势',
|
||||
'view_more_markets' => '查看更多市场',
|
||||
'why_choose_us' => '为什么选择我们?',
|
||||
'view_more_markets' => '查看更多',
|
||||
'pair' => '币对',
|
||||
'last_price' => '最新价',
|
||||
'24h_change' => '24h 涨跌',
|
||||
'market_cap' => '市值',
|
||||
|
||||
'why_choose_us' => '为什么选择 NovaEx?',
|
||||
'secure_storage' => '安全存储',
|
||||
'secure_storage_desc' => '我们将绝大部分数字资产存储在安全的离线存储中。',
|
||||
'protected_insurance' => '保险保护',
|
||||
@ -196,9 +171,11 @@ $translations = [
|
||||
'industry_best_practices' => '行业最佳实践',
|
||||
'industry_best_practices_desc' => 'NovaEx 支持多种最流行的数字货币。',
|
||||
'platform_desc' => '我们的平台为零售和机构交易者提供具有先进功能和稳健基础设施的无缝交易体验。',
|
||||
'partners' => '合作伙伴',
|
||||
|
||||
'global_partners' => '全球合作伙伴',
|
||||
'partners_subtitle' => '深受全球领先组织和金融机构的信任。',
|
||||
'footer_desc' => 'NovaEx 是全球领先的数字资产交易平台,为全球用户提供安全稳定的交易服务。',
|
||||
|
||||
'footer_desc' => 'NovaEx 是全球领先的数字资产 trading 平台,为全球用户提供安全稳定的交易服务。',
|
||||
'about' => '关于',
|
||||
'about_us' => '关于我们',
|
||||
'careers' => '职业介绍',
|
||||
@ -221,110 +198,57 @@ $translations = [
|
||||
'cookie_policy' => 'Cookie 政策',
|
||||
'security' => '安全',
|
||||
'system_status_normal' => '系统状态:正常',
|
||||
'personal_center' => '个人中心',
|
||||
'uid' => 'UID',
|
||||
'credit_score' => '信用分',
|
||||
'kyc_status' => '身份认证',
|
||||
'kyc_none' => '未认证',
|
||||
'kyc_pending' => '审核中',
|
||||
'kyc_approved' => '已认证',
|
||||
'kyc_rejected' => '认证失败',
|
||||
'kyc_submit' => '提交认证',
|
||||
'total_balance' => '总资产',
|
||||
'available_balance' => '可用余额',
|
||||
'order_book' => '订单簿',
|
||||
'trade_panel' => '下单面板',
|
||||
'k_line' => 'K线图',
|
||||
'open_orders' => '当前委托',
|
||||
'order_history' => '历史委托',
|
||||
'trade_history' => '成交记录',
|
||||
'funds_flow' => '资金流水',
|
||||
'current_positions' => '当前持仓',
|
||||
'limit' => '限价',
|
||||
'market' => '市价',
|
||||
|
||||
'search_pair' => '搜索币对',
|
||||
'search_contract' => '搜索合约',
|
||||
'price' => '价格',
|
||||
'amount' => '数量',
|
||||
'total' => '总额',
|
||||
'available' => '可用',
|
||||
'limit' => '限价',
|
||||
'market' => '市价',
|
||||
'buy' => '买入',
|
||||
'sell' => '卖出',
|
||||
'buy_long' => '看多/买入',
|
||||
'sell_short' => '看空/卖出',
|
||||
'open_long' => '买入开多',
|
||||
'open_short' => '卖出开空',
|
||||
'leverage' => '杠杆',
|
||||
'tp_sl' => '止盈止损',
|
||||
'take_profit' => '止盈',
|
||||
'stop_loss' => '止损',
|
||||
'cost' => '成本',
|
||||
'open_long' => '做多',
|
||||
'open_short' => '做空',
|
||||
'security_settings' => '安全设置',
|
||||
'asset_details' => '资产详情',
|
||||
'transaction_records' => '交易记录',
|
||||
'level' => '等级',
|
||||
'crypto_markets' => '加密货币行情',
|
||||
'24h_volume' => '24小时成交量',
|
||||
'fear_greed' => '贪婪恐惧指数',
|
||||
'btc_dominance' => '比特币占有率',
|
||||
'favorites' => '自选',
|
||||
'all_crypto' => '所有币种',
|
||||
'asset' => '资产',
|
||||
'24h_high_low' => '24小时最高/最低',
|
||||
'deposit_assets' => '充值资产',
|
||||
'deposit_method_tip' => '请选择您偏好的充值方式。',
|
||||
'fiat_deposit' => '法币充值',
|
||||
'crypto_deposit' => '加密货币充值',
|
||||
'bank_transfer' => '本地银行转账',
|
||||
'blockchain_transfer' => '区块链转账',
|
||||
'support_20_global' => '支持20多种全球货币',
|
||||
'safe_compliant' => '安全合规的通道',
|
||||
'fast_processing' => '24/7 快速处理',
|
||||
'no_service_fee' => '无服务费',
|
||||
'select_currency' => '选择币种',
|
||||
'deposit_amount' => '充值金额',
|
||||
'matching_instructions' => '匹配说明',
|
||||
'matching_tip' => '我们的智能匹配系统将为您匹配认证商户。确认后,您将收到银行账户详情。请在时限内完成转账。',
|
||||
'match_now' => '立即匹配商户',
|
||||
'select_network' => '选择网络',
|
||||
'get_address' => '获取充值地址',
|
||||
'withdraw_assets' => '提现资产',
|
||||
'withdraw_tip' => '安全地将 USDT 提现到您的外部钱包。',
|
||||
'withdraw_address' => '提现地址',
|
||||
'trading_password' => '交易密码',
|
||||
'submit_withdrawal' => '提交提现',
|
||||
'withdrawal_tips' => '提现提示',
|
||||
'withdrawal_tip_1' => '请仔细检查目标地址。我们无法找回发送到错误地址的资金。',
|
||||
'withdrawal_tip_2' => 'TRC20 提现通常在 5-10 分钟内到账。',
|
||||
'withdrawal_tip_3' => '高峰时段,提现将进行人工安全审计。',
|
||||
'withdrawal_tip_4' => '手续费:每笔交易 1 USDT。',
|
||||
'recent_history' => '最近记录',
|
||||
'no_records' => '暂无记录',
|
||||
'max' => '最大',
|
||||
'customer_service' => '在线客服',
|
||||
'chat_welcome' => '您好!请问有什么可以帮您?',
|
||||
'type_message' => '输入消息...',
|
||||
'matching_account' => '正在匹配收款账户...',
|
||||
'matching_desc' => '系统正在为您匹配安全的本地收款账户。请稍候。',
|
||||
'crypto' => '加密货币',
|
||||
'search_market' => '搜索币种',
|
||||
'more_pairs' => '更多币种',
|
||||
'limit_order' => '限价',
|
||||
'market_order' => '市价',
|
||||
'available' => '可用',
|
||||
'buy_long' => '买入开多',
|
||||
'sell_short' => '卖出开空',
|
||||
'open_position' => '开仓',
|
||||
'close_position' => '平仓',
|
||||
'cross' => '全仓',
|
||||
'margin' => '保证金',
|
||||
'isolated' => '逐仓',
|
||||
'cross' => '全仓',
|
||||
'order_book' => '订单簿',
|
||||
'open_orders' => '当前委托',
|
||||
'order_history' => '历史委托',
|
||||
'positions' => '当前持仓',
|
||||
'no_positions' => '暂无持仓',
|
||||
'perpetual' => '永续合约',
|
||||
'delivery' => '交割合约',
|
||||
'fee' => '手续费',
|
||||
'max_open' => '最大可开',
|
||||
'no_records' => '暂无记录',
|
||||
'cancel' => '取消',
|
||||
'confirm' => '确认',
|
||||
'adjust_leverage' => '调整杠杆',
|
||||
'close_position' => '平仓',
|
||||
'time' => '时间',
|
||||
'pair' => '币对',
|
||||
'side' => '方向',
|
||||
'filled' => '已成交',
|
||||
'status' => '状态',
|
||||
'load_more' => '加载更多',
|
||||
'action' => '操作',
|
||||
'type' => '类型',
|
||||
'direction' => '方向',
|
||||
'filled' => '已成交',
|
||||
|
||||
'settlement_time' => '结算时间',
|
||||
'buy_amount' => '买入金额',
|
||||
'min_order' => '最小下单',
|
||||
'buy_up' => '买涨',
|
||||
'buy_down' => '买跌',
|
||||
'profit' => '收益',
|
||||
'expected_profit' => '预期收益',
|
||||
'in_progress' => '进行中',
|
||||
'settled' => '已结算',
|
||||
'opening_price' => '买入价',
|
||||
'closing_price' => '结算价',
|
||||
'countdown' => '倒计时',
|
||||
'pnl' => '盈亏',
|
||||
'trading_executing' => '交易执行中',
|
||||
'waiting_settlement' => '等待结算',
|
||||
'system_matching_engine' => '系统撮合引擎',
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
293
index.php
293
index.php
@ -9,31 +9,31 @@ $trending_pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT'];
|
||||
|
||||
<main>
|
||||
<!-- Carousel Section (Constrained Width) -->
|
||||
<section class="hero-carousel-section" style="padding: 10px 0; background: #0b0e11;">
|
||||
<div class="carousel-container" style="max-width: 1200px; margin: 0 auto; position: relative; height: 450px; overflow: hidden; border-radius: 24px; box-shadow: 0 20px 50px rgba(0,0,0,0.5);">
|
||||
<div class="carousel-track" id="carouselTrack" style="display: flex; height: 100%; transition: transform 0.5s ease-in-out;">
|
||||
<section class="hero-carousel-section" style="padding: 20px 0; background: #0b0e11;">
|
||||
<div class="carousel-container" style="max-width: 1200px; margin: 0 auto; position: relative; height: 500px; overflow: hidden; border-radius: 24px; box-shadow: 0 30px 60px rgba(0,0,0,0.6);">
|
||||
<div class="carousel-track" id="carouselTrack" style="display: flex; height: 100%; transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);">
|
||||
<div class="carousel-slide" style="min-width: 100%; position: relative;">
|
||||
<img src="https://images.pexels.com/photos/6771574/pexels-photo-6771574.jpeg?auto=compress&cs=tinysrgb&w=1920" style="width: 100%; height: 100%; object-fit: cover; opacity: 0.6;">
|
||||
<div class="carousel-content" style="position: absolute; top: 50%; left: 8%; transform: translateY(-50%); color: white; max-width: 600px;">
|
||||
<h2 class="carousel-title" style="font-size: 3rem; font-weight: 800; margin-bottom: 20px; text-shadow: 0 5px 15px rgba(0,0,0,0.5);">NovaEx Global Launch</h2>
|
||||
<p class="carousel-desc" style="font-size: 1.1rem; opacity: 0.9; margin-bottom: 30px;">Experience the next generation of digital asset trading with ultra-low latency and bank-grade security.</p>
|
||||
<a href="register.php" class="btn-primary" style="padding: 12px 35px; border-radius: 8px; font-weight: bold; text-decoration: none; display: inline-block; background: var(--primary-color); color: white;"><?php echo __('join_now', 'Join Now'); ?></a>
|
||||
<div class="carousel-content" style="position: absolute; top: 50%; left: 8%; transform: translateY(-50%); color: white; max-width: 650px;">
|
||||
<h2 class="carousel-title" style="font-size: 3.5rem; font-weight: 800; margin-bottom: 25px; line-height: 1.1; text-shadow: 0 10px 20px rgba(0,0,0,0.5);">NovaEx Global Launch</h2>
|
||||
<p class="carousel-desc" style="font-size: 1.2rem; opacity: 0.9; margin-bottom: 35px; line-height: 1.6;">Experience the next generation of digital asset trading with ultra-low latency and bank-grade security.</p>
|
||||
<a href="register.php" class="btn-primary" style="padding: 15px 45px; border-radius: 12px; font-weight: bold; text-decoration: none; display: inline-block; background: var(--primary-color); color: white; font-size: 1.1rem; box-shadow: 0 10px 20px rgba(79, 172, 254, 0.3);"><?php echo __('join_now'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carousel-slide" style="min-width: 100%; position: relative;">
|
||||
<img src="https://images.pexels.com/photos/844124/pexels-photo-844124.jpeg?auto=compress&cs=tinysrgb&w=1920" style="width: 100%; height: 100%; object-fit: cover; opacity: 0.6;">
|
||||
<div class="carousel-content" style="position: absolute; top: 50%; left: 8%; transform: translateY(-50%); color: white; max-width: 600px;">
|
||||
<h2 class="carousel-title" style="font-size: 3rem; font-weight: 800; margin-bottom: 20px; text-shadow: 0 5px 15px rgba(0,0,0,0.5);">Trade Futures with 100x Leverage</h2>
|
||||
<p class="carousel-desc" style="font-size: 1.1rem; opacity: 0.9; margin-bottom: 30px;">Maximize your capital efficiency with our professional perpetual futures contracts.</p>
|
||||
<a href="futures.php" class="btn-primary" style="padding: 12px 35px; border-radius: 8px; font-weight: bold; text-decoration: none; display: inline-block; background: var(--primary-color); color: white;"><?php echo __('start_trading', 'Start Trading'); ?></a>
|
||||
<div class="carousel-content" style="position: absolute; top: 50%; left: 8%; transform: translateY(-50%); color: white; max-width: 650px;">
|
||||
<h2 class="carousel-title" style="font-size: 3.5rem; font-weight: 800; margin-bottom: 25px; line-height: 1.1; text-shadow: 0 10px 20px rgba(0,0,0,0.5);">Trade Futures with 100x Leverage</h2>
|
||||
<p class="carousel-desc" style="font-size: 1.2rem; opacity: 0.9; margin-bottom: 35px; line-height: 1.6;">Maximize your capital efficiency with our professional perpetual futures contracts.</p>
|
||||
<a href="futures.php" class="btn-primary" style="padding: 15px 45px; border-radius: 12px; font-weight: bold; text-decoration: none; display: inline-block; background: var(--primary-color); color: white; font-size: 1.1rem;"><?php echo __('start_trading'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carousel-slide" style="min-width: 100%; position: relative;">
|
||||
<img src="https://images.pexels.com/photos/6771178/pexels-photo-6771178.jpeg?auto=compress&cs=tinysrgb&w=1920" style="width: 100%; height: 100%; object-fit: cover; opacity: 0.6;">
|
||||
<div class="carousel-content" style="position: absolute; top: 50%; left: 8%; transform: translateY(-50%); color: white; max-width: 600px;">
|
||||
<h2 class="carousel-title" style="font-size: 3rem; font-weight: 800; margin-bottom: 20px; text-shadow: 0 5px 15px rgba(0,0,0,0.5);">Secure Crypto Staking</h2>
|
||||
<p class="carousel-desc" style="font-size: 1.1rem; opacity: 0.9; margin-bottom: 30px;">Earn passive income on your idle assets with our high-yield staking pools.</p>
|
||||
<a href="mining.php" class="btn-primary" style="padding: 12px 35px; border-radius: 8px; font-weight: bold; text-decoration: none; display: inline-block; background: var(--primary-color); color: white;"><?php echo __('earn_now', 'Earn Now'); ?></a>
|
||||
<div class="carousel-content" style="position: absolute; top: 50%; left: 8%; transform: translateY(-50%); color: white; max-width: 650px;">
|
||||
<h2 class="carousel-title" style="font-size: 3.5rem; font-weight: 800; margin-bottom: 25px; line-height: 1.1; text-shadow: 0 10px 20px rgba(0,0,0,0.5);">Secure Crypto Staking</h2>
|
||||
<p class="carousel-desc" style="font-size: 1.2rem; opacity: 0.9; margin-bottom: 35px; line-height: 1.6;">Earn passive income on your idle assets with our high-yield staking pools.</p>
|
||||
<a href="mining.php" class="btn-primary" style="padding: 15px 45px; border-radius: 12px; font-weight: bold; text-decoration: none; display: inline-block; background: var(--primary-color); color: white; font-size: 1.1rem;"><?php echo __('earn_now'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -46,20 +46,20 @@ $trending_pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT'];
|
||||
</section>
|
||||
|
||||
<!-- Market Trends -->
|
||||
<section class="container" style="padding: 40px 20px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 20px;">
|
||||
<h2 class="section-title-home" style="font-size: 2rem; font-weight: 800; margin: 0;"><?php echo __('market_trends', '市场趋势'); ?></h2>
|
||||
<a href="markets.php" style="color: var(--primary-color); text-decoration: none; font-weight: 600; font-size: 14px;"><?php echo __('view_more_markets', '查看更多'); ?> <i class="fas fa-chevron-right" style="font-size: 10px;"></i></a>
|
||||
<section class="container" style="padding: 60px 20px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 30px;">
|
||||
<h2 class="section-title-home" style="font-size: 2.2rem; font-weight: 800; margin: 0;"><?php echo __('market_trends'); ?></h2>
|
||||
<a href="markets.php" style="color: var(--primary-color); text-decoration: none; font-weight: 600; font-size: 15px;"><?php echo __('view_more_markets'); ?> <i class="fas fa-chevron-right" style="font-size: 11px; margin-left: 5px;"></i></a>
|
||||
</div>
|
||||
|
||||
<div class="market-table-container" style="background: var(--card-bg); border-radius: 20px; border: 1px solid var(--border-color); overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.2);">
|
||||
<div class="market-table-container" style="background: var(--card-bg); border-radius: 24px; border: 1px solid var(--border-color); overflow: hidden; box-shadow: 0 15px 40px rgba(0,0,0,0.3);">
|
||||
<table class="market-table" style="width: 100%; border-collapse: collapse; text-align: left; min-width: 600px;">
|
||||
<thead>
|
||||
<tr style="border-bottom: 1px solid var(--border-color); background: rgba(255,255,255,0.02);">
|
||||
<th style="padding: 15px 20px; color: var(--text-muted); font-weight: 500; font-size: 13px;"><?php echo __('pair', '币对'); ?></th>
|
||||
<th style="padding: 15px 20px; color: var(--text-muted); font-weight: 500; font-size: 13px;"><?php echo __('last_price', '最新价'); ?></th>
|
||||
<th style="padding: 15px 20px; color: var(--text-muted); font-weight: 500; font-size: 13px;"><?php echo __('24h_change', '24h 涨跌'); ?></th>
|
||||
<th class="desktop-only-cell" style="padding: 15px 20px; color: var(--text-muted); font-weight: 500; font-size: 13px;"><?php echo __('market_cap', '市值'); ?></th>
|
||||
<tr style="border-bottom: 1px solid var(--border-color); background: rgba(255,255,255,0.03);">
|
||||
<th style="padding: 20px 25px; color: var(--text-muted); font-weight: 600; font-size: 14px;"><?php echo __('pair'); ?></th>
|
||||
<th style="padding: 20px 25px; color: var(--text-muted); font-weight: 600; font-size: 14px;"><?php echo __('last_price'); ?></th>
|
||||
<th style="padding: 20px 25px; color: var(--text-muted); font-weight: 600; font-size: 14px;"><?php echo __('24h_change'); ?></th>
|
||||
<th class="desktop-only-cell" style="padding: 20px 25px; color: var(--text-muted); font-weight: 600; font-size: 14px;"><?php echo __('market_cap'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="home-market-list">
|
||||
@ -69,147 +69,158 @@ $trending_pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT'];
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Download Section -->
|
||||
<section style="padding: 60px 0; background: #0b0e11; border-top: 1px solid rgba(255,255,255,0.05);">
|
||||
<div class="container">
|
||||
<div class="download-grid" style="display: flex; align-items: center; justify-content: space-between; gap: 40px; flex-wrap: wrap;">
|
||||
<div style="flex: 1.2; min-width: 300px;">
|
||||
<h2 class="section-title-small" style="font-size: 2.2rem; font-weight: 800; margin-bottom: 20px; background: linear-gradient(135deg, #fff 0%, #848e9c 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">Trade Anywhere, Anytime</h2>
|
||||
<p style="color: var(--text-muted); font-size: 1rem; line-height: 1.6; margin-bottom: 30px;">Stay connected to the markets with the NovaEx mobile app. Experience professional trading features in the palm of your hand.</p>
|
||||
|
||||
<div class="features-mini-grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 30px;">
|
||||
<div style="display: flex; gap: 12px; align-items: flex-start;">
|
||||
<div style="width: 36px; height: 36px; border-radius: 10px; background: rgba(79, 172, 254, 0.1); display: flex; align-items: center; justify-content: center; color: var(--primary-color); flex-shrink: 0;">
|
||||
<i class="fas fa-bolt" style="font-size: 14px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 3px; font-weight: 700; font-size: 0.95rem;">Fast & Secure</h4>
|
||||
<p style="font-size: 0.85rem; color: #848e9c; margin: 0;">Military-grade encryption.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 12px; align-items: flex-start;">
|
||||
<div style="width: 36px; height: 36px; border-radius: 10px; background: rgba(0, 192, 135, 0.1); display: flex; align-items: center; justify-content: center; color: #00c087; flex-shrink: 0;">
|
||||
<i class="fas fa-chart-line" style="font-size: 14px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 3px; font-weight: 700; font-size: 0.95rem;">Real-time</h4>
|
||||
<p style="font-size: 0.85rem; color: #848e9c; margin: 0;">Low-latency updates.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="flex: 1; display: flex; flex-direction: column; gap: 15px; min-width: 280px;">
|
||||
<a href="app.php" style="text-decoration: none;">
|
||||
<div class="download-card-new" style="background: rgba(255,255,255,0.03); padding: 20px; border-radius: 16px; border: 1px solid rgba(255,255,255,0.08); display: flex; align-items: center; gap: 15px; transition: 0.3s;">
|
||||
<div style="width: 50px; height: 50px; background: #000; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.6rem;">
|
||||
<i class="fab fa-apple" style="color: white;"></i>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-size: 0.75rem; color: #848e9c;">Download on the</div>
|
||||
<div style="font-size: 1.1rem; font-weight: 800; color: white;">App Store</div>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right" style="color: #848e9c;"></i>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="app.php" style="text-decoration: none;">
|
||||
<div class="download-card-new" style="background: rgba(255,255,255,0.03); padding: 20px; border-radius: 16px; border: 1px solid rgba(255,255,255,0.08); display: flex; align-items: center; gap: 15px; transition: 0.3s;">
|
||||
<div style="width: 50px; height: 50px; background: #000; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.4rem;">
|
||||
<i class="fab fa-google-play" style="color: #3DDC84;"></i>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-size: 0.75rem; color: #848e9c;">Get it on</div>
|
||||
<div style="font-size: 1.1rem; font-weight: 800; color: white;">Google Play</div>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right" style="color: #848e9c;"></i>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div style="display: flex; gap: 15px; align-items: center; background: linear-gradient(135deg, rgba(79, 172, 254, 0.1) 0%, rgba(0, 242, 254, 0.1) 100%); padding: 15px; border-radius: 16px; border: 1px solid rgba(79, 172, 254, 0.2);">
|
||||
<div style="background: white; padding: 8px; border-radius: 10px;">
|
||||
<i class="fas fa-qrcode" style="font-size: 2rem; color: #000;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight: 700; color: white; font-size: 0.9rem;">Scan to Download</div>
|
||||
<div style="font-size: 0.75rem; color: #848e9c;">iOS & Android</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Why Choose Us -->
|
||||
<section class="container" style="padding: 60px 20px;">
|
||||
<div style="text-align: center; margin-bottom: 50px;">
|
||||
<h2 class="section-title-home" style="font-size: 2.2rem; font-weight: 800; margin-bottom: 15px;"><?php echo __('why_choose_us', '为什么选择 NovaEx?'); ?></h2>
|
||||
<p style="color: var(--text-muted); max-width: 600px; margin: 0 auto; font-size: 1rem;"><?php echo __('platform_desc'); ?></p>
|
||||
<section class="container" style="padding: 80px 20px; border-top: 1px solid rgba(255,255,255,0.05);">
|
||||
<div style="text-align: center; margin-bottom: 60px;">
|
||||
<h2 class="section-title-home" style="font-size: 2.8rem; font-weight: 800; margin-bottom: 20px;"><?php echo __('why_choose_us'); ?></h2>
|
||||
<p style="color: var(--text-muted); max-width: 700px; margin: 0 auto; font-size: 1.1rem; line-height: 1.7;"><?php echo __('platform_desc'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="grid-3">
|
||||
<div class="choose-card" style="padding: 40px 30px; background: rgba(255,255,255,0.02); border-radius: 24px; border: 1px solid rgba(255,255,255,0.05); text-align: center; transition: all 0.4s;">
|
||||
<div style="width: 70px; height: 70px; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px; color: white; font-size: 1.8rem;">
|
||||
<div class="grid-3" style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px;">
|
||||
<div class="choose-card" style="padding: 50px 40px; background: rgba(255,255,255,0.02); border-radius: 32px; border: 1px solid rgba(255,255,255,0.05); text-align: center; transition: all 0.4s ease;">
|
||||
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); border-radius: 24px; display: flex; align-items: center; justify-content: center; margin: 0 auto 30px; color: white; font-size: 2rem; box-shadow: 0 10px 20px rgba(79, 172, 254, 0.3);">
|
||||
<i class="fas fa-shield-alt"></i>
|
||||
</div>
|
||||
<h3 style="margin-bottom: 15px; font-size: 1.4rem; font-weight: 700;"><?php echo __('secure_storage', 'Secure Storage'); ?></h3>
|
||||
<p style="color: var(--text-muted); line-height: 1.6; font-size: 0.9rem;"><?php echo __('secure_storage_desc'); ?></p>
|
||||
<h3 style="margin-bottom: 18px; font-size: 1.5rem; font-weight: 700; color: white;"><?php echo __('secure_storage'); ?></h3>
|
||||
<p style="color: var(--text-muted); line-height: 1.7; font-size: 1rem;"><?php echo __('secure_storage_desc'); ?></p>
|
||||
</div>
|
||||
<div class="choose-card" style="padding: 40px 30px; background: rgba(255,255,255,0.02); border-radius: 24px; border: 1px solid rgba(255,255,255,0.05); text-align: center; transition: all 0.4s;">
|
||||
<div style="width: 70px; height: 70px; background: linear-gradient(135deg, #00c087 0%, #00d2ff 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px; color: white; font-size: 1.8rem;">
|
||||
<div class="choose-card" style="padding: 50px 40px; background: rgba(255,255,255,0.02); border-radius: 32px; border: 1px solid rgba(255,255,255,0.05); text-align: center; transition: all 0.4s ease;">
|
||||
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, #00c087 0%, #00d2ff 100%); border-radius: 24px; display: flex; align-items: center; justify-content: center; margin: 0 auto 30px; color: white; font-size: 2rem; box-shadow: 0 10px 20px rgba(0, 192, 135, 0.3);">
|
||||
<i class="fas fa-user-lock"></i>
|
||||
</div>
|
||||
<h3 style="margin-bottom: 15px; font-size: 1.4rem; font-weight: 700;"><?php echo __('protected_insurance', 'Protected by Insurance'); ?></h3>
|
||||
<p style="color: var(--text-muted); line-height: 1.6; font-size: 0.9rem;"><?php echo __('protected_insurance_desc'); ?></p>
|
||||
<h3 style="margin-bottom: 18px; font-size: 1.5rem; font-weight: 700; color: white;"><?php echo __('protected_insurance'); ?></h3>
|
||||
<p style="color: var(--text-muted); line-height: 1.7; font-size: 1rem;"><?php echo __('protected_insurance_desc'); ?></p>
|
||||
</div>
|
||||
<div class="choose-card" style="padding: 40px 30px; background: rgba(255,255,255,0.02); border-radius: 24px; border: 1px solid rgba(255,255,255,0.05); text-align: center; transition: all 0.4s;">
|
||||
<div style="width: 70px; height: 70px; background: linear-gradient(135deg, #f0b90b 0%, #ff9a00 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px; color: white; font-size: 1.8rem;">
|
||||
<div class="choose-card" style="padding: 50px 40px; background: rgba(255,255,255,0.02); border-radius: 32px; border: 1px solid rgba(255,255,255,0.05); text-align: center; transition: all 0.4s ease;">
|
||||
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, #f0b90b 0%, #ff9a00 100%); border-radius: 24px; display: flex; align-items: center; justify-content: center; margin: 0 auto 30px; color: white; font-size: 2rem; box-shadow: 0 10px 20px rgba(240, 185, 11, 0.3);">
|
||||
<i class="fas fa-microchip"></i>
|
||||
</div>
|
||||
<h3 style="margin-bottom: 15px; font-size: 1.4rem; font-weight: 700;"><?php echo __('industry_best_practices', 'Best Practices'); ?></h3>
|
||||
<p style="color: var(--text-muted); line-height: 1.6; font-size: 0.9rem;"><?php echo __('industry_best_practices_desc'); ?></p>
|
||||
<h3 style="margin-bottom: 18px; font-size: 1.5rem; font-weight: 700; color: white;"><?php echo __('industry_best_practices'); ?></h3>
|
||||
<p style="color: var(--text-muted); line-height: 1.7; font-size: 1rem;"><?php echo __('industry_best_practices_desc'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Partners -->
|
||||
<section style="padding: 60px 0; background: #161a1e;">
|
||||
<section style="padding: 100px 0; background: #0b0e11; border-top: 1px solid rgba(255,255,255,0.05);">
|
||||
<div class="container" style="text-align: center;">
|
||||
<h2 style="font-size: 1.8rem; font-weight: 800; margin-bottom: 40px;"><?php echo __('global_partners'); ?></h2>
|
||||
<div class="partners-grid-custom" style="display: grid; grid-template-columns: repeat(6, 1fr); gap: 20px;">
|
||||
<div class="partner-item"><i class="fab fa-google-pay" style="font-size: 2rem; color: #4285F4;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-apple-pay" style="font-size: 2rem; color: #ffffff;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-visa" style="font-size: 2rem; color: #1a1f71;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-mastercard" style="font-size: 2rem; color: #eb001b;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-paypal" style="font-size: 2rem; color: #003087;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-stripe" style="font-size: 2rem; color: #6772e5;"></i></div>
|
||||
<h2 style="font-size: 2.2rem; font-weight: 800; margin-bottom: 15px;"><?php echo __('global_partners'); ?></h2>
|
||||
<p style="color: var(--text-muted); margin-bottom: 60px; font-size: 1.1rem;"><?php echo __('partners_subtitle'); ?></p>
|
||||
<div class="partners-grid-custom" style="display: grid; grid-template-columns: repeat(6, 1fr); gap: 25px;">
|
||||
<div class="partner-item"><i class="fab fa-google-pay" style="font-size: 2.5rem; color: #4285F4;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-apple-pay" style="font-size: 2.5rem; color: #ffffff;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-visa" style="font-size: 2.5rem; color: #1a1f71;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-mastercard" style="font-size: 2.5rem; color: #eb001b;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-paypal" style="font-size: 2.5rem; color: #003087;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-stripe" style="font-size: 2.5rem; color: #6772e5;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-amazon-pay" style="font-size: 2.5rem; color: #FF9900;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-alipay" style="font-size: 2.5rem; color: #00A3EE;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-cc-amex" style="font-size: 2.5rem; color: #007bc1;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-cc-discover" style="font-size: 2.5rem; color: #ff6000;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-cc-diners-club" style="font-size: 2.5rem; color: #004a97;"></i></div>
|
||||
<div class="partner-item"><i class="fab fa-cc-jcb" style="font-size: 2.5rem; color: #003184;"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Download Section -->
|
||||
<section style="padding: 100px 0; background: linear-gradient(to bottom, #0b0e11, #161a1e);">
|
||||
<div class="container">
|
||||
<div class="download-grid" style="display: flex; align-items: center; justify-content: space-between; gap: 60px; flex-wrap: wrap;">
|
||||
<div style="flex: 1.2; min-width: 300px;">
|
||||
<h2 class="section-title-small" style="font-size: 3rem; font-weight: 800; margin-bottom: 25px; background: linear-gradient(135deg, #fff 0%, #848e9c 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; line-height: 1.2;">Trade Anywhere, Anytime</h2>
|
||||
<p style="color: var(--text-muted); font-size: 1.2rem; line-height: 1.8; margin-bottom: 40px;">Stay connected to the markets with the NovaEx mobile app. Experience professional trading features in the palm of your hand.</p>
|
||||
|
||||
<div class="features-mini-grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: 40px;">
|
||||
<div style="display: flex; gap: 15px; align-items: flex-start;">
|
||||
<div style="width: 44px; height: 44px; border-radius: 14px; background: rgba(79, 172, 254, 0.1); display: flex; align-items: center; justify-content: center; color: var(--primary-color); flex-shrink: 0;">
|
||||
<i class="fas fa-bolt" style="font-size: 18px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px; font-weight: 700; font-size: 1.1rem; color: white;">Fast & Secure</h4>
|
||||
<p style="font-size: 0.95rem; color: #848e9c; margin: 0; line-height: 1.4;">Military-grade encryption for all your data.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 15px; align-items: flex-start;">
|
||||
<div style="width: 44px; height: 44px; border-radius: 14px; background: rgba(0, 192, 135, 0.1); display: flex; align-items: center; justify-content: center; color: #00c087; flex-shrink: 0;">
|
||||
<i class="fas fa-chart-line" style="font-size: 18px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px; font-weight: 700; font-size: 1.1rem; color: white;">Real-time</h4>
|
||||
<p style="font-size: 0.95rem; color: #848e9c; margin: 0; line-height: 1.4;">Low-latency updates and market depth.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="flex: 1; display: flex; flex-direction: column; gap: 20px; min-width: 320px;">
|
||||
<a href="app.php" style="text-decoration: none;">
|
||||
<div class="download-card-new" style="background: rgba(255,255,255,0.03); padding: 25px; border-radius: 20px; border: 1px solid rgba(255,255,255,0.08); display: flex; align-items: center; gap: 20px; transition: all 0.3s ease;">
|
||||
<div style="width: 60px; height: 60px; background: #000; border-radius: 16px; display: flex; align-items: center; justify-content: center; font-size: 2rem;">
|
||||
<i class="fab fa-apple" style="color: white;"></i>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-size: 0.85rem; color: #848e9c;">Download on the</div>
|
||||
<div style="font-size: 1.3rem; font-weight: 800; color: white;">App Store</div>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right" style="color: #848e9c;"></i>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="app.php" style="text-decoration: none;">
|
||||
<div class="download-card-new" style="background: rgba(255,255,255,0.03); padding: 25px; border-radius: 20px; border: 1px solid rgba(255,255,255,0.08); display: flex; align-items: center; gap: 20px; transition: all 0.3s ease;">
|
||||
<div style="width: 60px; height: 60px; background: #000; border-radius: 16px; display: flex; align-items: center; justify-content: center; font-size: 1.8rem;">
|
||||
<i class="fab fa-google-play" style="color: #3DDC84;"></i>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-size: 0.85rem; color: #848e9c;">Get it on</div>
|
||||
<div style="font-size: 1.3rem; font-weight: 800; color: white;">Google Play</div>
|
||||
</div>
|
||||
<i class="fas fa-chevron-right" style="color: #848e9c;"></i>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div style="display: flex; gap: 20px; align-items: center; background: linear-gradient(135deg, rgba(79, 172, 254, 0.1) 0%, rgba(0, 242, 254, 0.1) 100%); padding: 20px; border-radius: 20px; border: 1px solid rgba(79, 172, 254, 0.2);">
|
||||
<div style="background: white; padding: 12px; border-radius: 14px; box-shadow: 0 5px 15px rgba(0,0,0,0.2);">
|
||||
<i class="fas fa-qrcode" style="font-size: 2.5rem; color: #000;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight: 800; color: white; font-size: 1.1rem; margin-bottom: 4px;">Scan to Download</div>
|
||||
<div style="font-size: 0.9rem; color: #848e9c;">Support for iOS & Android</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.carousel-dot.active { opacity: 1 !important; width: 30px !important; border-radius: 6px !important; background: var(--primary-color) !important; }
|
||||
.partner-item { padding: 25px 15px; background: rgba(255,255,255,0.02); border-radius: 16px; transition: 0.3s; display: flex; align-items: center; justify-content: center; }
|
||||
.partner-item:hover { background: rgba(255,255,255,0.05); transform: translateY(-3px); }
|
||||
.carousel-dot.active { opacity: 1 !important; width: 35px !important; border-radius: 8px !important; background: var(--primary-color) !important; }
|
||||
.partner-item { padding: 30px 20px; background: rgba(255,255,255,0.02); border-radius: 20px; transition: 0.3s; display: flex; align-items: center; justify-content: center; border: 1px solid rgba(255,255,255,0.03); }
|
||||
.partner-item:hover { background: rgba(255,255,255,0.05); transform: translateY(-5px); border-color: rgba(255,255,255,0.1); }
|
||||
|
||||
.download-card-new:hover { background: rgba(255,255,255,0.06) !important; border-color: var(--primary-color) !important; }
|
||||
.choose-card:hover { transform: translateY(-10px); border-color: var(--primary-color) !important; background: rgba(79, 172, 254, 0.05) !important; }
|
||||
.download-card-new:hover { background: rgba(255,255,255,0.06) !important; border-color: var(--primary-color) !important; transform: translateX(5px); }
|
||||
.choose-card:hover { transform: translateY(-15px); border-color: var(--primary-color) !important; background: rgba(79, 172, 254, 0.05) !important; }
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.carousel-container { height: 350px !important; border-radius: 0 !important; }
|
||||
.carousel-title { font-size: 1.8rem !important; }
|
||||
.carousel-desc { font-size: 0.9rem !important; margin-bottom: 20px !important; }
|
||||
.carousel-container { height: 400px !important; border-radius: 0 !important; }
|
||||
.carousel-title { font-size: 2.2rem !important; }
|
||||
.carousel-desc { font-size: 1rem !important; margin-bottom: 25px !important; }
|
||||
.partners-grid-custom { grid-template-columns: repeat(3, 1fr) !important; }
|
||||
.grid-3 { grid-template-columns: 1fr !important; }
|
||||
.section-title-home { font-size: 2.2rem !important; }
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.carousel-container { height: 300px !important; }
|
||||
.carousel-title { font-size: 1.5rem !important; }
|
||||
.section-title-home { font-size: 1.5rem !important; }
|
||||
.carousel-container { height: 350px !important; }
|
||||
.carousel-title { font-size: 1.8rem !important; }
|
||||
.section-title-home { font-size: 1.8rem !important; }
|
||||
.partners-grid-custom { grid-template-columns: repeat(2, 1fr) !important; }
|
||||
.desktop-only-cell { display: none; }
|
||||
.features-mini-grid { grid-template-columns: 1fr !important; }
|
||||
.download-grid { gap: 40px !important; }
|
||||
.section-title-small { font-size: 2.2rem !important; }
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -237,7 +248,7 @@ $trending_pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT'];
|
||||
updateCarousel();
|
||||
}
|
||||
|
||||
setInterval(nextSlide, 5000);
|
||||
setInterval(nextSlide, 6000);
|
||||
|
||||
const trendingPairs = <?php echo json_encode($trending_pairs); ?>;
|
||||
const homeWs = new WebSocket('wss://stream.binance.com:9443/ws/' + trendingPairs.map(p => p.toLowerCase() + '@ticker').join('/'));
|
||||
@ -259,16 +270,16 @@ $trending_pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT'];
|
||||
const name = p.replace('USDT', '');
|
||||
html += `
|
||||
<tr style="border-bottom: 1px solid rgba(255,255,255,0.05);">
|
||||
<td style="padding: 15px 20px; display: flex; align-items: center; gap: 10px;">
|
||||
<img src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png" width="28" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<td style="padding: 20px 25px; display: flex; align-items: center; gap: 15px;">
|
||||
<img src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png" width="32" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<div>
|
||||
<div style="font-weight: 700; font-size: 0.95rem;">${name}</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-muted);">USDT</div>
|
||||
<div style="font-weight: 700; font-size: 1.1rem; color: white;">${name}</div>
|
||||
<div style="font-size: 0.8rem; color: var(--text-muted);">USDT</div>
|
||||
</div>
|
||||
</td>
|
||||
<td style="padding: 15px 20px; font-weight: 600; font-size: 0.95rem; color: #EAECEF;">$ ${parseFloat(d.c).toLocaleString()}</td>
|
||||
<td style="padding: 15px 20px; color: ${color}; font-weight: 700; font-size: 0.95rem;">${d.P >= 0 ? '+' : ''}${d.P}%</td>
|
||||
<td class="desktop-only-cell" style="padding: 15px 20px; color: var(--text-muted); font-size: 0.85rem;">$ ${(parseFloat(d.q) / 1000000).toFixed(2)}M</td>
|
||||
<td style="padding: 20px 25px; font-weight: 600; font-size: 1.1rem; color: #EAECEF;">$ ${parseFloat(d.c).toLocaleString()}</td>
|
||||
<td style="padding: 20px 25px; color: ${color}; font-weight: 700; font-size: 1.1rem;">${d.P >= 0 ? '+' : ''}${d.P}%</td>
|
||||
<td class="desktop-only-cell" style="padding: 20px 25px; color: var(--text-muted); font-size: 1rem;">$ ${(parseFloat(d.q) / 1000000).toFixed(2)}M</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
565
options.php
565
options.php
@ -27,64 +27,111 @@ if ($user_id) {
|
||||
--input-bg: #1e2329;
|
||||
}
|
||||
|
||||
body { background-color: var(--bg-color); color: var(--text-primary); font-family: 'PingFang SC', sans-serif; margin: 0; overflow-y: auto !important; }
|
||||
body { background-color: var(--bg-color); color: var(--text-primary); font-family: 'Inter', 'PingFang SC', sans-serif; margin: 0; overflow-y: auto !important; }
|
||||
|
||||
.trading-layout { display: flex; gap: 1px; background: var(--border-color); padding: 0; min-height: calc(100vh - 64px); }
|
||||
.panel { background: var(--panel-bg); display: flex; flex-direction: column; }
|
||||
|
||||
/* Market Panel */
|
||||
.market-panel { width: 280px; flex-shrink: 0; border-right: 1px solid var(--border-color); }
|
||||
#pairs-list { height: 600px; overflow-y: auto; }
|
||||
.pair-item { display: flex; justify-content: space-between; padding: 10px 12px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.02); }
|
||||
.pair-item.active { background: rgba(240, 185, 11, 0.1); }
|
||||
.market-panel { width: 300px; flex-shrink: 0; border-right: 1px solid var(--border-color); }
|
||||
#pairs-list { height: calc(100vh - 120px); overflow-y: auto; scrollbar-width: thin; }
|
||||
.pair-item { display: flex; align-items: center; padding: 10px 16px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.02); transition: 0.2s; }
|
||||
.pair-item:hover { background: rgba(255,255,255,0.05); }
|
||||
.pair-item.active { background: rgba(240, 185, 11, 0.08); border-left: 3px solid var(--accent-color); }
|
||||
.pair-icon { width: 24px; height: 24px; margin-right: 12px; border-radius: 50%; }
|
||||
|
||||
/* Center Panel */
|
||||
.center-panel { flex: 1; background: var(--bg-color); display: flex; flex-direction: column; }
|
||||
.info-bar { height: 60px; display: flex; align-items: center; padding: 0 15px; gap: 15px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); }
|
||||
.chart-container { height: 420px; background: var(--bg-color); border-bottom: 1px solid var(--border-color); }
|
||||
.center-panel { flex: 1; background: var(--bg-color); display: flex; flex-direction: column; min-width: 0; }
|
||||
.info-bar { height: 66px; display: flex; align-items: center; padding: 0 20px; gap: 25px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); }
|
||||
.chart-container { height: 550px; background: var(--bg-color); border-bottom: 1px solid var(--border-color); }
|
||||
|
||||
/* Option Order Panel */
|
||||
.option-order-panel { padding: 20px; background: var(--panel-bg); border-bottom: 1px solid var(--border-color); }
|
||||
.duration-list { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 5px; -webkit-overflow-scrolling: touch; }
|
||||
.duration-item { flex-shrink: 0; padding: 8px 15px; background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 6px; cursor: pointer; text-align: center; min-width: 85px; }
|
||||
.duration-item.active { border-color: var(--accent-color); color: var(--accent-color); background: rgba(240, 185, 11, 0.1); }
|
||||
.duration-item .profit { display: block; font-size: 10px; margin-top: 2px; }
|
||||
.option-order-panel { padding: 20px 25px; background: var(--panel-bg); border-bottom: 1px solid var(--border-color); }
|
||||
.duration-list { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; margin-bottom: 15px; }
|
||||
.duration-item { padding: 10px 5px; background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 8px; cursor: pointer; text-align: center; transition: 0.2s; position: relative; }
|
||||
.duration-item:hover { border-color: rgba(240, 185, 11, 0.5); }
|
||||
.duration-item.active { border-color: var(--accent-color); background: rgba(240, 185, 11, 0.1); }
|
||||
.duration-item .time { font-size: 14px; font-weight: 700; color: white; display: block; }
|
||||
.duration-item .profit { font-size: 11px; font-weight: 600; color: var(--accent-color); margin-top: 2px; display: block; }
|
||||
|
||||
.option-input-wrapper { background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 6px; display: flex; align-items: center; padding: 10px 15px; margin-top: 8px; }
|
||||
.option-input-wrapper input { flex: 1; background: transparent; border: none; color: white; outline: none; font-size: 16px; text-align: right; }
|
||||
.option-input-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 25px; align-items: start; }
|
||||
.option-input-wrapper { background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 8px; display: flex; align-items: center; padding: 10px 15px; margin-top: 6px; transition: 0.2s; }
|
||||
.option-input-wrapper:focus-within { border-color: var(--accent-color); }
|
||||
.option-input-wrapper input { flex: 1; background: transparent; border: none; color: white; outline: none; font-size: 18px; text-align: right; font-weight: 700; font-family: 'Roboto Mono', monospace; width: 100%; }
|
||||
|
||||
.action-buttons { display: flex; gap: 15px; margin-top: 20px; }
|
||||
.action-btn { flex: 1; padding: 15px; border: none; border-radius: 8px; font-weight: bold; font-size: 16px; cursor: pointer; color: white; display: flex; flex-direction: column; align-items: center; gap: 4px; }
|
||||
.action-btn { flex: 1; padding: 12px; border: none; border-radius: 8px; font-weight: 700; font-size: 16px; cursor: pointer; color: white; display: flex; flex-direction: column; align-items: center; gap: 4px; transition: 0.2s; text-transform: uppercase; }
|
||||
.action-btn:active { transform: scale(0.98); }
|
||||
.action-btn.up { background: var(--up-color); }
|
||||
.action-btn.down { background: var(--down-color); }
|
||||
.action-btn span { font-size: 11px; font-weight: normal; opacity: 0.9; }
|
||||
.action-btn i { font-size: 16px; }
|
||||
.action-btn span { font-size: 11px; font-weight: 500; opacity: 0.9; }
|
||||
|
||||
/* Order Book Panel */
|
||||
.order-book-panel { width: 320px; flex-shrink: 0; border-left: 1px solid var(--border-color); display: flex; flex-direction: column; }
|
||||
.ob-header { padding: 12px 16px; font-size: 12px; color: var(--text-secondary); border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; font-weight: 600; }
|
||||
.ob-row { display: flex; justify-content: space-between; padding: 4px 16px; font-size: 12px; position: relative; font-family: 'Roboto Mono', monospace; cursor: pointer; }
|
||||
.ob-row:hover { background: rgba(255,255,255,0.05); }
|
||||
.ob-vol-bar { position: absolute; top: 0; right: 0; bottom: 0; z-index: 0; opacity: 0.15; transition: width 0.3s; }
|
||||
|
||||
/* Countdown Modal */
|
||||
.countdown-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); display: none; align-items: center; justify-content: center; z-index: 3000; backdrop-filter: blur(8px); }
|
||||
.countdown-content { background: #1c2127; border: 1px solid var(--border-color); border-radius: 24px; width: 420px; padding: 40px; text-align: center; box-shadow: 0 25px 50px rgba(0,0,0,0.5); position: relative; overflow: hidden; }
|
||||
.countdown-content::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 4px; background: linear-gradient(90deg, var(--accent-color), #ffeb3b); }
|
||||
|
||||
.countdown-timer-wrap { position: relative; width: 140px; height: 140px; margin: 0 auto 30px; display: flex; align-items: center; justify-content: center; }
|
||||
.countdown-circle { position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
|
||||
.countdown-circle circle { fill: none; stroke-width: 8; stroke-linecap: round; }
|
||||
.countdown-circle .bg { stroke: rgba(255,255,255,0.05); }
|
||||
.countdown-circle .progress { stroke: var(--accent-color); stroke-dasharray: 414; stroke-dashoffset: 0; transition: stroke-dashoffset 1s linear; }
|
||||
|
||||
#countdown-number { font-size: 48px; font-weight: 900; color: white; font-family: 'Roboto Mono'; }
|
||||
.modal-pair { font-size: 20px; font-weight: 800; margin-bottom: 5px; }
|
||||
.modal-dir { font-size: 14px; font-weight: 700; margin-bottom: 20px; text-transform: uppercase; }
|
||||
|
||||
.modal-info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; background: rgba(255,255,255,0.03); padding: 20px; border-radius: 16px; margin-bottom: 25px; border: 1px solid rgba(255,255,255,0.05); }
|
||||
.modal-info-item { text-align: left; }
|
||||
.modal-info-label { font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.5px; font-weight: 700; }
|
||||
.modal-info-value { font-size: 15px; font-weight: 700; color: white; margin-top: 3px; }
|
||||
|
||||
.modal-tips { font-size: 12px; color: var(--text-secondary); line-height: 1.6; font-style: italic; }
|
||||
|
||||
/* Settlement Result Modal */
|
||||
.result-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.9); display: none; align-items: center; justify-content: center; z-index: 3100; backdrop-filter: blur(10px); }
|
||||
.result-content { background: #1c2127; border-radius: 24px; width: 380px; padding: 40px; text-align: center; border: 1px solid var(--border-color); animation: resultPop 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); }
|
||||
@keyframes resultPop { from { transform: scale(0.8); opacity: 0; } to { transform: scale(1); opacity: 1; } }
|
||||
.result-icon { width: 80px; height: 80px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px; font-size: 40px; color: white; }
|
||||
.result-icon.win { background: linear-gradient(135deg, #00c087, #00d2ff); box-shadow: 0 10px 30px rgba(0,192,135,0.4); }
|
||||
.result-icon.loss { background: linear-gradient(135deg, #f6465d, #ff9a9e); box-shadow: 0 10px 30px rgba(246,70,93,0.4); }
|
||||
.result-title { font-size: 28px; font-weight: 900; margin-bottom: 10px; }
|
||||
.result-pnl { font-size: 32px; font-weight: 900; margin-bottom: 30px; font-family: 'Roboto Mono'; }
|
||||
.result-close { width: 100%; padding: 14px; border: none; border-radius: 12px; background: var(--accent-color); color: #000; font-weight: 800; cursor: pointer; font-size: 16px; }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 1400px) {
|
||||
.market-panel { width: 260px; }
|
||||
.order-book-panel { width: 280px; }
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
.market-panel { display: none; }
|
||||
}
|
||||
@media (max-width: 992px) {
|
||||
.trading-layout { flex-direction: column; }
|
||||
.order-book-panel { display: none; }
|
||||
.chart-container { height: 320px; }
|
||||
.info-bar { height: auto; padding: 10px 15px; flex-wrap: wrap; }
|
||||
.order-book-panel { width: 100%; border-left: none; border-top: 1px solid var(--border-color); }
|
||||
.chart-container { height: 400px; }
|
||||
.option-input-grid { grid-template-columns: 1fr; }
|
||||
.info-bar { height: auto; padding: 15px; flex-wrap: wrap; gap: 15px; }
|
||||
}
|
||||
@media (max-width: 576px) {
|
||||
.action-buttons { gap: 10px; }
|
||||
.action-btn { padding: 12px 5px; font-size: 14px; }
|
||||
.countdown-card { width: 90% !important; margin: 0 5%; }
|
||||
}
|
||||
|
||||
#order-countdown-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); display: none; align-items: center; justify-content: center; z-index: 9999; backdrop-filter: blur(5px); }
|
||||
.countdown-card { background: #1e2329; width: 380px; border-radius: 24px; border: 1px solid #2b3139; overflow: hidden; box-shadow: 0 20px 60px rgba(0,0,0,0.5); }
|
||||
.timer-circle { width: 100px; height: 100px; border: 4px solid var(--accent-color); border-radius: 50%; margin: 0 auto 20px; display: flex; align-items: center; justify-content: center; font-size: 28px; font-weight: bold; color: var(--accent-color); }
|
||||
</style>
|
||||
|
||||
<div class="trading-layout">
|
||||
<!-- Left Panel -->
|
||||
<!-- Left Panel (Market Pairs) -->
|
||||
<div class="panel market-panel">
|
||||
<div style="padding: 12px; border-bottom: 1px solid var(--border-color);">
|
||||
<input type="text" id="market-search" placeholder="搜索币对" style="width: 100%; background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 8px 12px; border-radius: 6px; font-size: 13px; outline: none;">
|
||||
<div style="padding: 15px; border-bottom: 1px solid var(--border-color);">
|
||||
<div style="position: relative;">
|
||||
<i class="fas fa-search" style="position: absolute; left: 12px; top: 12px; color: var(--text-secondary); font-size: 14px;"></i>
|
||||
<input type="text" id="market-search" placeholder="<?php echo __('search_pair'); ?>" style="width: 100%; background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 10px 12px 10px 35px; border-radius: 8px; font-size: 13px; outline: none;">
|
||||
</div>
|
||||
</div>
|
||||
<div id="pairs-list"></div>
|
||||
</div>
|
||||
@ -92,17 +139,18 @@ if ($user_id) {
|
||||
<!-- Center Panel -->
|
||||
<div class="panel center-panel">
|
||||
<div class="info-bar">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<img id="current-logo" src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" width="28" height="28" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<span id="current-pair-display" style="font-size: 16px; font-weight: bold;">BTC/USDT</span>
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<img id="current-logo" src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" width="32" height="32" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<span id="current-pair-display" style="font-size: 20px; font-weight: 800; letter-spacing: -0.5px;">BTC/USDT</span>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column;">
|
||||
<span id="last-price" style="font-size: 16px; font-weight: bold; color: var(--up-color);">--</span>
|
||||
<span id="price-change" style="font-size: 11px; color: var(--up-color);">--</span>
|
||||
<span id="last-price" style="font-size: 18px; font-weight: 700; color: var(--up-color); font-family: 'Roboto Mono', monospace;">--</span>
|
||||
<span id="price-change" style="font-size: 12px; color: var(--up-color); font-weight: 600;">--</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 15px; margin-left: auto; font-size: 11px;" class="desktop-only">
|
||||
<div style="color: var(--text-secondary);">24h高 <span id="high-24h" style="color: white; margin-left: 3px;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h低 <span id="low-24h" style="color: white; margin-left: 3px;">--</span></div>
|
||||
<div style="display: flex; gap: 30px; margin-left: auto; font-size: 12px;" class="desktop-only">
|
||||
<div style="color: var(--text-secondary);">24h High <span id="high-24h" style="color: white; display: block; margin-top: 4px; font-weight: 600;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h Low <span id="low-24h" style="color: white; display: block; margin-top: 4px; font-weight: 600;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h Vol <span id="vol-24h" style="color: white; display: block; margin-top: 4px; font-weight: 600;">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -112,83 +160,155 @@ if ($user_id) {
|
||||
|
||||
<div class="center-content">
|
||||
<div class="option-order-panel">
|
||||
<div style="color: var(--text-secondary); font-size: 12px; margin-bottom: 10px;">结算时间</div>
|
||||
<div style="color: var(--text-secondary); font-size: 12px; margin-bottom: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px;"><?php echo __('settlement_time'); ?></div>
|
||||
<div class="duration-list">
|
||||
<div class="duration-item active" data-seconds="60" data-min="10" data-profit="8">60S <span class="profit">收益 8%</span></div>
|
||||
<div class="duration-item" data-seconds="90" data-min="100" data-profit="15">90S <span class="profit">收益 15%</span></div>
|
||||
<div class="duration-item" data-seconds="180" data-min="500" data-profit="30">180S <span class="profit">收益 30%</span></div>
|
||||
<div class="duration-item" data-seconds="300" data-min="1000" data-profit="50">300S <span class="profit">收益 50%</span></div>
|
||||
<div class="duration-item" data-seconds="600" data-min="5000" data-profit="80">600S <span class="profit">收益 80%</span></div>
|
||||
<div class="duration-item active" data-seconds="60" data-profit="8">
|
||||
<span class="time">60S</span>
|
||||
<span class="profit"><?php echo __('profit'); ?> 8%</span>
|
||||
</div>
|
||||
<div class="duration-item" data-seconds="90" data-profit="12">
|
||||
<span class="time">90S</span>
|
||||
<span class="profit"><?php echo __('profit'); ?> 12%</span>
|
||||
</div>
|
||||
<div class="duration-item" data-seconds="120" data-profit="20">
|
||||
<span class="time">120S</span>
|
||||
<span class="profit"><?php echo __('profit'); ?> 20%</span>
|
||||
</div>
|
||||
<div class="duration-item" data-seconds="180" data-profit="20">
|
||||
<span class="time">180S</span>
|
||||
<span class="profit"><?php echo __('profit'); ?> 20%</span>
|
||||
</div>
|
||||
<div class="duration-item" data-seconds="300" data-profit="32">
|
||||
<span class="time">300S</span>
|
||||
<span class="profit"><?php echo __('profit'); ?> 32%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; color: var(--text-secondary);">
|
||||
<span>买入金额</span>
|
||||
<span>余额: <span id="user-balance" style="color: white;"><?php echo number_format($balance, 2); ?></span> USDT</span>
|
||||
<div class="option-input-grid">
|
||||
<div>
|
||||
<div style="font-size: 12px; color: var(--text-secondary); font-weight: 700; margin-bottom: 8px;">
|
||||
<span><?php echo __('buy_amount'); ?></span>
|
||||
</div>
|
||||
<div class="option-input-wrapper">
|
||||
<input type="number" id="order-amount" placeholder="<?php echo __('min_order'); ?> 10" oninput="calculateExpectedProfit()">
|
||||
<span style="color: var(--text-secondary); margin-left: 10px; font-size: 14px; font-weight: 700;">USDT</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-input-wrapper">
|
||||
<input type="number" id="order-amount" placeholder="最小下单 10">
|
||||
<span style="color: var(--text-secondary); margin-left: 10px; font-size: 14px;">USDT</span>
|
||||
<div>
|
||||
<div style="background: rgba(255,255,255,0.02); padding: 12px 18px; border-radius: 8px; border: 1px solid var(--border-color); height: 50px; display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;">
|
||||
<span style="color: var(--text-secondary); font-size: 12px; font-weight: 600;"><?php echo __('expected_profit'); ?>:</span>
|
||||
<span id="expected-profit-display" style="color: var(--accent-color); font-weight: 800; font-size: 16px; font-family: 'Roboto Mono';">0.00 USDT</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; padding: 0 5px;">
|
||||
<span style="color: var(--text-secondary); font-size: 12px; font-weight: 600;"><?php echo __('available'); ?>:</span>
|
||||
<span style="color: var(--accent-color); font-weight: 800; font-size: 16px;"><span id="user-balance"><?php echo number_format($balance, 2); ?></span> USDT</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button class="action-btn up" onclick="placeOptionOrder('up')">买涨 ↑<span id="up-profit-text">收益 8%</span></button>
|
||||
<button class="action-btn down" onclick="placeOptionOrder('down')">买跌 ↓<span id="down-profit-text">收益 8%</span></button>
|
||||
<button class="action-btn up" onclick="placeOptionOrder('up')">
|
||||
<i class="fas fa-arrow-up"></i>
|
||||
<?php echo __('buy_up'); ?>
|
||||
<span id="up-profit-text"><?php echo __('profit'); ?> 8%</span>
|
||||
</button>
|
||||
<button class="action-btn down" onclick="placeOptionOrder('down')">
|
||||
<i class="fas fa-arrow-down"></i>
|
||||
<?php echo __('buy_down'); ?>
|
||||
<span id="down-profit-text"><?php echo __('profit'); ?> 8%</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 15px; overflow-x: auto; background: var(--panel-bg);">
|
||||
<div style="padding: 20px; background: var(--panel-bg); margin-bottom: 20px;">
|
||||
<div style="display: flex; gap: 20px; border-bottom: 1px solid var(--border-color); margin-bottom: 15px;">
|
||||
<button onclick="switchTab(this, 'pending')" style="background: none; border: none; color: var(--accent-color); padding: 10px 0; border-bottom: 2px solid var(--accent-color); font-size: 14px; cursor: pointer;">进行中</button>
|
||||
<button onclick="switchTab(this, 'completed')" style="background: none; border: none; color: var(--text-secondary); padding: 10px 0; font-size: 14px; cursor: pointer;">已结算</button>
|
||||
<button class="tab-btn active" onclick="switchTab(this, 'pending')" style="background: none; border: none; color: var(--accent-color); padding: 12px 0; border-bottom: 2px solid var(--accent-color); font-size: 14px; font-weight: 700; cursor: pointer;"><?php echo __('in_progress'); ?></button>
|
||||
<button class="tab-btn" onclick="switchTab(this, 'completed')" style="background: none; border: none; color: var(--text-secondary); padding: 12px 0; font-size: 14px; font-weight: 700; cursor: pointer;"><?php echo __('settled'); ?></button>
|
||||
</div>
|
||||
<div style="overflow-x: auto;">
|
||||
<table style="width: 100%; border-collapse: collapse; min-width: 800px; font-size: 13px;">
|
||||
<thead style="color: var(--text-secondary); text-align: left; background: rgba(255,255,255,0.01);">
|
||||
<tr>
|
||||
<th style="padding: 12px 10px;"><?php echo __('time'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('pair'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('direction'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('amount'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('opening_price'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('closing_price'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('status'); ?></th>
|
||||
<th style="padding: 12px 10px; text-align: right;"><?php echo __('pnl'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="orders-tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<table style="width: 100%; border-collapse: collapse; min-width: 600px; font-size: 11px;">
|
||||
<thead style="color: var(--text-secondary); text-align: left;">
|
||||
<tr>
|
||||
<th style="padding: 8px 4px;">时间</th>
|
||||
<th style="padding: 8px 4px;">币对</th>
|
||||
<th style="padding: 8px 4px;">方向</th>
|
||||
<th style="padding: 8px 4px;">金额</th>
|
||||
<th style="padding: 8px 4px;">买入价</th>
|
||||
<th style="padding: 8px 4px;">结算价</th>
|
||||
<th style="padding: 8px 4px;">倒计时</th>
|
||||
<th style="padding: 8px 4px; text-align: right;">盈亏</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="orders-tbody">
|
||||
<tr><td colspan="8" style="text-align: center; padding: 40px;">暂无记录</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order Book (Hidden on mobile) -->
|
||||
<!-- Right Panel (Order Book) -->
|
||||
<div class="panel order-book-panel">
|
||||
<div style="padding: 10px 15px; font-size: 12px; color: var(--text-secondary); border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between;">
|
||||
<span>价格(USDT)</span>
|
||||
<span>数量(BTC)</span>
|
||||
<div class="ob-header">
|
||||
<span>Price(USDT)</span>
|
||||
<span>Amount(<span class="asset-name">BTC</span>)</span>
|
||||
</div>
|
||||
<div id="asks-list" style="display: flex; flex-direction: column-reverse;"></div>
|
||||
<div id="ob-mid-price" style="padding: 10px 0; text-align: center; font-weight: bold; font-size: 16px; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);">--</div>
|
||||
<div id="bids-list"></div>
|
||||
<div id="asks-list" style="display: flex; flex-direction: column-reverse; flex: 1; overflow: hidden;"></div>
|
||||
<div style="padding: 15px; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); text-align: center; background: rgba(255,255,255,0.01);">
|
||||
<div id="ob-mid-price" style="font-size: 18px; font-weight: 800; font-family: 'Roboto Mono', monospace;">--</div>
|
||||
</div>
|
||||
<div id="bids-list" style="flex: 1; overflow: hidden;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="order-countdown-modal">
|
||||
<div class="countdown-card">
|
||||
<div style="padding: 20px; text-align: center; border-bottom: 1px solid #2b3139; background: #161a1e; font-weight: bold;">交易执行中</div>
|
||||
<div style="padding: 25px; text-align: center;">
|
||||
<div class="timer-circle" id="modal-timer">60s</div>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; text-align: left; background: rgba(255,255,255,0.03); padding: 15px; border-radius: 12px; font-size: 13px;">
|
||||
<div><div style="color: var(--text-secondary); margin-bottom: 4px;">币对</div><div id="modal-symbol" style="font-weight: bold;">--</div></div>
|
||||
<div><div style="color: var(--text-secondary); margin-bottom: 4px;">方向</div><div id="modal-direction" style="font-weight: bold;">--</div></div>
|
||||
<div><div style="color: var(--text-secondary); margin-bottom: 4px;">买入金额</div><div id="modal-amount" style="font-weight: bold;">--</div></div>
|
||||
<div><div style="color: var(--text-secondary); margin-bottom: 4px;">买入价</div><div id="modal-price" style="font-weight: bold;">--</div></div>
|
||||
</div>
|
||||
<button onclick="closeCountdownModal()" style="width: 100%; margin-top: 25px; padding: 12px; background: #2b3139; border: none; color: white; border-radius: 12px; cursor: pointer;">等待结算</button>
|
||||
<!-- Countdown Modal -->
|
||||
<div class="countdown-modal" id="order-modal">
|
||||
<div class="countdown-content">
|
||||
<div class="countdown-timer-wrap">
|
||||
<svg class="countdown-circle">
|
||||
<circle class="bg" cx="70" cy="70" r="66"></circle>
|
||||
<circle class="progress" id="progress-circle" cx="70" cy="70" r="66"></circle>
|
||||
</svg>
|
||||
<div id="countdown-number">60</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-pair" id="modal-pair-text">BTC/USDT</div>
|
||||
<div class="modal-dir" id="modal-dir-text">BUY UP</div>
|
||||
|
||||
<div class="modal-info-grid">
|
||||
<div class="modal-info-item">
|
||||
<div class="modal-info-label"><?php echo __('opening_price'); ?></div>
|
||||
<div class="modal-info-value" id="modal-open-price">--</div>
|
||||
</div>
|
||||
<div class="modal-info-item">
|
||||
<div class="modal-info-label"><?php echo __('amount'); ?></div>
|
||||
<div class="modal-info-value" id="modal-amount">0.00 USDT</div>
|
||||
</div>
|
||||
<div class="modal-info-item">
|
||||
<div class="modal-info-label"><?php echo __('current_price'); ?></div>
|
||||
<div class="modal-info-value" id="modal-curr-price" style="color: var(--accent-color);">--</div>
|
||||
</div>
|
||||
<div class="modal-info-item">
|
||||
<div class="modal-info-label"><?php echo __('expected_profit'); ?></div>
|
||||
<div class="modal-info-value" id="modal-expected" style="color: var(--up-color);">0.00 USDT</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-tips">
|
||||
<?php echo __('order_processing_tip'); ?>: <?php echo __('market_volatility_notice'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settlement Result Modal -->
|
||||
<div class="result-modal" id="result-modal">
|
||||
<div class="result-content">
|
||||
<div class="result-icon" id="result-icon">
|
||||
<i class="fas fa-check"></i>
|
||||
</div>
|
||||
<div class="result-title" id="result-title">CONGRATULATIONS!</div>
|
||||
<div style="color: var(--text-secondary); font-size: 14px; margin-bottom: 20px;"><?php echo __('settlement_complete'); ?></div>
|
||||
<div class="result-pnl" id="result-pnl">+0.00 USDT</div>
|
||||
<button class="result-close" onclick="closeResult()"><?php echo __('confirm'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -196,18 +316,22 @@ if ($user_id) {
|
||||
<script>
|
||||
let currentPair = 'BTCUSDT';
|
||||
let currentPrice = 0;
|
||||
let marketData = {};
|
||||
let activeTab = 'pending';
|
||||
let selectedDuration = 60;
|
||||
let selectedProfit = 0.08;
|
||||
let selectedMinAmount = 10;
|
||||
let marketData = {};
|
||||
let activeTab = 'pending';
|
||||
let countdownInterval;
|
||||
let currentOrderId = null;
|
||||
const lang = '<?php echo $lang; ?>';
|
||||
|
||||
const pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT', 'ADAUSDT', 'DOGEUSDT', 'AVAXUSDT', 'DOTUSDT', 'LINKUSDT'];
|
||||
const pairs = [
|
||||
'BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT', 'XRPUSDT', 'ADAUSDT', 'AVAXUSDT', 'DOGEUSDT', 'DOTUSDT', 'LINKUSDT',
|
||||
'MATICUSDT', 'NEARUSDT', 'LTCUSDT', 'ATOMUSDT', 'UNIUSDT', 'XLMUSDT', 'ALGOUSDT', 'TRXUSDT', 'BCHUSDT', 'SHIBUSDT'
|
||||
];
|
||||
|
||||
function initChart(symbol) {
|
||||
new TradingView.widget({
|
||||
"width": "100%", "height": "100%", "symbol": "BINANCE:" + symbol, "interval": "1", "theme": "dark", "style": "1", "locale": "zh_CN", "container_id": "tv_chart_container", "backgroundColor": "#0b0e11", "hide_side_toolbar": true, "allow_symbol_change": false
|
||||
"width": "100%", "height": "100%", "symbol": "BINANCE:" + symbol, "interval": "1", "theme": "dark", "style": "1", "locale": lang === 'zh' ? 'zh_CN' : 'en', "container_id": "tv_chart_container", "backgroundColor": "#0b0e11", "hide_side_toolbar": true, "allow_symbol_change": false, "save_image": false
|
||||
});
|
||||
}
|
||||
initChart(currentPair);
|
||||
@ -230,9 +354,21 @@ if ($user_id) {
|
||||
document.getElementById('last-price').innerText = currentPrice.toLocaleString();
|
||||
document.getElementById('last-price').style.color = data.P >= 0 ? 'var(--up-color)' : 'var(--down-color)';
|
||||
document.getElementById('price-change').innerText = (data.P >= 0 ? '+' : '') + data.P + '%';
|
||||
document.getElementById('price-change').style.color = data.P >= 0 ? 'var(--up-color)' : 'var(--down-color)';
|
||||
document.getElementById('high-24h').innerText = parseFloat(data.h).toLocaleString();
|
||||
document.getElementById('low-24h').innerText = parseFloat(data.l).toLocaleString();
|
||||
document.getElementById('vol-24h').innerText = parseFloat(data.v).toLocaleString();
|
||||
document.getElementById('ob-mid-price').innerText = currentPrice.toLocaleString();
|
||||
if (document.getElementById('high-24h')) document.getElementById('high-24h').innerText = parseFloat(data.h).toLocaleString();
|
||||
if (document.getElementById('low-24h')) document.getElementById('low-24h').innerText = parseFloat(data.l).toLocaleString();
|
||||
document.getElementById('ob-mid-price').style.color = data.P >= 0 ? 'var(--up-color)' : 'var(--down-color)';
|
||||
|
||||
if (document.getElementById('order-modal').style.display === 'flex') {
|
||||
document.getElementById('modal-curr-price').innerText = currentPrice.toLocaleString();
|
||||
const openPrice = parseFloat(document.getElementById('modal-open-price').innerText.replace(/,/g, ''));
|
||||
const dir = document.getElementById('modal-dir-text').innerText.toLowerCase();
|
||||
const isWin = (dir.includes('up') && currentPrice > openPrice) || (dir.includes('down') && currentPrice < openPrice);
|
||||
document.getElementById('modal-curr-price').style.color = isWin ? 'var(--up-color)' : 'var(--down-color)';
|
||||
}
|
||||
|
||||
updateOrderBook();
|
||||
}
|
||||
|
||||
@ -241,33 +377,65 @@ if ($user_id) {
|
||||
if (!list) return;
|
||||
let html = '';
|
||||
pairs.forEach(p => {
|
||||
const d = marketData[p] || {c: 0, P: 0};
|
||||
html += `<div class="pair-item ${currentPair === p ? 'active' : ''}" onclick="switchPair('${p}')">
|
||||
<span>${p.replace('USDT', '/USDT')}</span>
|
||||
<span style="color: ${d.P >= 0 ? 'var(--up-color)' : 'var(--down-color)'}">${parseFloat(d.c).toLocaleString()}</span>
|
||||
</div>`;
|
||||
const d = marketData[p] || {c: 0, P: 0, v: 0};
|
||||
const name = p.replace('USDT', '');
|
||||
const icon = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png`;
|
||||
html += `
|
||||
<div class="pair-item ${currentPair === p ? 'active' : ''}" onclick="switchPair('${p}')">
|
||||
<img src="${icon}" class="pair-icon" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; font-size: 14px;">${name}/USDT</div>
|
||||
<div style="font-size: 11px; color: var(--text-secondary);">Vol ${parseFloat(d.v).toLocaleString()}</div>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<div style="font-weight: 600; font-family: 'Roboto Mono', monospace; font-size: 13px;">${parseFloat(d.c).toLocaleString()}</div>
|
||||
<div style="color: ${d.P >= 0 ? 'var(--up-color)' : 'var(--down-color)'}; font-size: 11px; font-weight: 600;">${(d.P >= 0 ? '+' : '') + d.P}%</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
list.innerHTML = html;
|
||||
}
|
||||
|
||||
function switchPair(p) {
|
||||
if (currentPair === p) return;
|
||||
currentPair = p;
|
||||
document.getElementById('current-pair-display').innerText = p.replace('USDT', '/USDT');
|
||||
document.getElementById('current-logo').src = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${p.replace('USDT','').toLowerCase()}.png`;
|
||||
const name = p.replace('USDT', '');
|
||||
document.getElementById('current-pair-display').innerText = name + '/USDT';
|
||||
document.getElementById('current-logo').src = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png`;
|
||||
document.querySelectorAll('.asset-name').forEach(el => el.innerText = name);
|
||||
initChart(p);
|
||||
renderPairs();
|
||||
}
|
||||
|
||||
function updateOrderBook() {
|
||||
const asks = document.getElementById('asks-list');
|
||||
const bids = document.getElementById('bids-list');
|
||||
if (!asks || !bids) return;
|
||||
let aH = ''; let bH = '';
|
||||
for(let i=0; i<10; i++) {
|
||||
aH += `<div class="ob-row"><span style="color: var(--down-color);">${(currentPrice*(1+(i+1)*0.001)).toFixed(2)}</span><span>${Math.random().toFixed(4)}</span></div>`;
|
||||
bH += `<div class="ob-row"><span style="color: var(--up-color);">${(currentPrice*(1-(i+1)*0.001)).toFixed(2)}</span><span>${Math.random().toFixed(4)}</span></div>`;
|
||||
let asksHtml = ''; let bidsHtml = '';
|
||||
let maxVol = 0;
|
||||
const rows = 15;
|
||||
const askData = []; const bidData = [];
|
||||
for(let i=0; i<rows; i++) {
|
||||
const av = Math.random() * 2 + 0.1; const bv = Math.random() * 2 + 0.1;
|
||||
askData.push(av); bidData.push(bv); maxVol = Math.max(maxVol, av, bv);
|
||||
}
|
||||
asks.innerHTML = aH; bids.innerHTML = bH;
|
||||
for(let i=0; i<rows; i++) {
|
||||
const ap = currentPrice * (1 + (i+1)*0.0002); const bp = currentPrice * (1 - (i+1)*0.0002);
|
||||
const av = askData[i]; const bv = bidData[i];
|
||||
asksHtml += `
|
||||
<div class="ob-row">
|
||||
<div class="ob-vol-bar" style="width: ${(av/maxVol*100)}%; background: var(--down-color);"></div>
|
||||
<span style="color: var(--down-color); font-weight: 600; z-index: 1;">${ap.toFixed(2)}</span>
|
||||
<span style="color: white; opacity: 0.9; z-index: 1;">${av.toFixed(4)}</span>
|
||||
</div>`;
|
||||
bidsHtml += `
|
||||
<div class="ob-row">
|
||||
<div class="ob-vol-bar" style="width: ${(bv/maxVol*100)}%; background: var(--up-color);"></div>
|
||||
<span style="color: var(--up-color); font-weight: 600; z-index: 1;">${bp.toFixed(2)}</span>
|
||||
<span style="color: white; opacity: 0.9; z-index: 1;">${bv.toFixed(4)}</span>
|
||||
</div>`;
|
||||
}
|
||||
asks.innerHTML = asksHtml; bids.innerHTML = bidsHtml;
|
||||
}
|
||||
|
||||
document.querySelectorAll('.duration-item').forEach(item => {
|
||||
@ -276,84 +444,167 @@ if ($user_id) {
|
||||
this.classList.add('active');
|
||||
selectedDuration = parseInt(this.dataset.seconds);
|
||||
selectedProfit = parseInt(this.dataset.profit) / 100;
|
||||
selectedMinAmount = parseInt(this.dataset.min);
|
||||
document.getElementById('order-amount').placeholder = `最小下单 ${selectedMinAmount}`;
|
||||
document.getElementById('up-profit-text').innerText = `收益 ${this.dataset.profit}%`;
|
||||
document.getElementById('down-profit-text').innerText = `收益 ${this.dataset.profit}%`;
|
||||
document.getElementById('up-profit-text').innerText = `${lang === 'zh' ? '收益' : 'Profit'} ${this.dataset.profit}%`;
|
||||
document.getElementById('down-profit-text').innerText = `${lang === 'zh' ? '收益' : 'Profit'} ${this.dataset.profit}%`;
|
||||
calculateExpectedProfit();
|
||||
});
|
||||
});
|
||||
|
||||
async function placeOptionOrder(dir) {
|
||||
function calculateExpectedProfit() {
|
||||
const amount = parseFloat(document.getElementById('order-amount').value) || 0;
|
||||
const profit = amount * selectedProfit;
|
||||
document.getElementById('expected-profit-display').innerText = `${profit.toFixed(2)} USDT`;
|
||||
}
|
||||
|
||||
async function placeOptionOrder(direction) {
|
||||
const amount = parseFloat(document.getElementById('order-amount').value);
|
||||
if (!amount || amount < selectedMinAmount) return alert(`最小金额为 ${selectedMinAmount}`);
|
||||
if (!amount || amount <= 0) return alert(lang === 'zh' ? '请输入有效金额' : 'Please enter a valid amount');
|
||||
if (currentPrice <= 0) return alert(lang === 'zh' ? '正在获取价格,请稍后' : 'Fetching price, please wait');
|
||||
|
||||
const resp = await fetch('api/place_option_order.php', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
symbol: currentPair, amount: amount, direction: dir,
|
||||
duration: selectedDuration, profit_rate: selectedProfit, opening_price: currentPrice
|
||||
symbol: currentPair,
|
||||
amount: amount,
|
||||
direction: direction,
|
||||
duration: selectedDuration,
|
||||
opening_price: currentPrice
|
||||
})
|
||||
});
|
||||
const res = await resp.json();
|
||||
if (res.success) {
|
||||
currentOrderId = res.order_id;
|
||||
document.getElementById('user-balance').innerText = res.new_balance.toFixed(2);
|
||||
showModal(dir, amount, currentPrice, selectedDuration);
|
||||
showCountdownModal(direction, amount, currentPrice, selectedDuration);
|
||||
fetchOrders();
|
||||
} else { alert(res.error); }
|
||||
} else {
|
||||
alert(res.error);
|
||||
}
|
||||
}
|
||||
|
||||
function showModal(dir, amt, pr, sec) {
|
||||
document.getElementById('modal-symbol').innerText = currentPair;
|
||||
document.getElementById('modal-direction').innerText = dir === 'up' ? '买涨 ↑' : '买跌 ↓';
|
||||
document.getElementById('modal-direction').style.color = dir === 'up' ? 'var(--up-color)' : 'var(--down-color)';
|
||||
document.getElementById('modal-amount').innerText = amt + ' USDT';
|
||||
document.getElementById('modal-price').innerText = pr.toLocaleString();
|
||||
document.getElementById('modal-timer').innerText = sec + 's';
|
||||
document.getElementById('order-countdown-modal').style.display = 'flex';
|
||||
let left = sec;
|
||||
function showCountdownModal(dir, amount, price, duration) {
|
||||
const modal = document.getElementById('order-modal');
|
||||
document.getElementById('modal-pair-text').innerText = currentPair.replace('USDT', '/USDT');
|
||||
document.getElementById('modal-dir-text').innerText = (dir === 'up' ? (lang === 'zh' ? '买涨' : 'BUY UP') : (lang === 'zh' ? '买跌' : 'BUY DOWN'));
|
||||
document.getElementById('modal-dir-text').style.color = dir === 'up' ? 'var(--up-color)' : 'var(--down-color)';
|
||||
document.getElementById('modal-open-price').innerText = price.toLocaleString();
|
||||
document.getElementById('modal-amount').innerText = amount.toFixed(2) + ' USDT';
|
||||
document.getElementById('modal-expected').innerText = (amount * selectedProfit).toFixed(2) + ' USDT';
|
||||
document.getElementById('modal-curr-price').innerText = price.toLocaleString();
|
||||
|
||||
const num = document.getElementById('countdown-number');
|
||||
const progress = document.getElementById('progress-circle');
|
||||
let timeLeft = duration;
|
||||
num.innerText = timeLeft;
|
||||
|
||||
modal.style.display = 'flex';
|
||||
|
||||
const totalOffset = 414;
|
||||
progress.style.strokeDashoffset = 0;
|
||||
|
||||
if (countdownInterval) clearInterval(countdownInterval);
|
||||
|
||||
countdownInterval = setInterval(() => {
|
||||
left--;
|
||||
document.getElementById('modal-timer').innerText = left + 's';
|
||||
if (left <= 0) { clearInterval(countdownInterval); closeCountdownModal(); fetchOrders(); }
|
||||
timeLeft--;
|
||||
num.innerText = timeLeft;
|
||||
const offset = totalOffset - (timeLeft / duration) * totalOffset;
|
||||
progress.style.strokeDashoffset = offset;
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
clearInterval(countdownInterval);
|
||||
checkResult();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function closeCountdownModal() { document.getElementById('order-countdown-modal').style.display = 'none'; }
|
||||
async function checkResult() {
|
||||
const resp = await fetch(`api/get_option_orders.php?status=completed&limit=1`);
|
||||
const res = await resp.json();
|
||||
document.getElementById('order-modal').style.display = 'none';
|
||||
|
||||
if (res.success && res.data.length > 0) {
|
||||
const order = res.data[0];
|
||||
const isWin = parseFloat(order.profit) > 0;
|
||||
|
||||
const resultModal = document.getElementById('result-modal');
|
||||
const icon = document.getElementById('result-icon');
|
||||
const title = document.getElementById('result-title');
|
||||
const pnl = document.getElementById('result-pnl');
|
||||
|
||||
icon.className = 'result-icon ' + (isWin ? 'win' : 'loss');
|
||||
icon.innerHTML = isWin ? '<i class="fas fa-trophy"></i>' : '<i class="fas fa-times"></i>';
|
||||
title.innerText = isWin ? (lang === 'zh' ? '恭喜获利' : 'CONGRATULATIONS!') : (lang === 'zh' ? '结算完成' : 'SETTLED');
|
||||
title.style.color = isWin ? 'var(--up-color)' : 'var(--text-primary)';
|
||||
pnl.innerText = (isWin ? '+' : '') + parseFloat(order.profit).toFixed(2) + ' USDT';
|
||||
pnl.style.color = isWin ? 'var(--up-color)' : 'var(--down-color)';
|
||||
|
||||
resultModal.style.display = 'flex';
|
||||
fetchOrders();
|
||||
|
||||
// Refresh balance
|
||||
const bResp = await fetch('api/get_assets.php');
|
||||
const bRes = await bResp.json();
|
||||
if (bRes.success) {
|
||||
const usdt = bRes.data.find(a => a.symbol === 'USDT');
|
||||
if (usdt) document.getElementById('user-balance').innerText = parseFloat(usdt.amount).toFixed(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function closeResult() {
|
||||
document.getElementById('result-modal').style.display = 'none';
|
||||
}
|
||||
|
||||
async function fetchOrders() {
|
||||
const resp = await fetch(`api/get_option_orders.php?status=${activeTab}`);
|
||||
const res = await resp.json();
|
||||
const tbody = document.getElementById('orders-tbody');
|
||||
if (res.success && res.data.length > 0) {
|
||||
tbody.innerHTML = res.data.map(o => {
|
||||
const isWin = o.result === 'win';
|
||||
const isLoss = o.result === 'loss';
|
||||
return `<tr style="border-bottom: 1px solid var(--border-color);">
|
||||
<td style="padding: 8px 4px;">${o.created_at}</td>
|
||||
<td style="padding: 8px 4px; font-weight: bold;">${o.symbol}</td>
|
||||
<td style="padding: 8px 4px; color: ${o.direction === 'up' ? 'var(--up-color)' : 'var(--down-color)'}">${o.direction === 'up' ? '↑' : '↓'}</td>
|
||||
<td style="padding: 8px 4px;">${parseFloat(o.amount).toFixed(2)}</td>
|
||||
<td style="padding: 8px 4px;">${parseFloat(o.opening_price).toLocaleString()}</td>
|
||||
<td style="padding: 8px 4px;">${o.closing_price ? parseFloat(o.closing_price).toLocaleString() : '--'}</td>
|
||||
<td style="padding: 8px 4px;">${o.status === 'pending' ? '进行中' : '已结算'}</td>
|
||||
<td style="padding: 8px 4px; text-align: right; color: ${isWin ? 'var(--up-color)' : (isLoss ? 'var(--down-color)' : 'white')}; font-weight: bold;">
|
||||
${isWin ? '+' + parseFloat(o.profit).toFixed(2) : (isLoss ? '-' + parseFloat(o.amount).toFixed(2) : '--')}
|
||||
tbody.innerHTML = res.data.map(o => `
|
||||
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||
<td style="padding: 12px 10px;">${o.created_at}</td>
|
||||
<td style="padding: 12px 10px; font-weight: 700;">${o.symbol}</td>
|
||||
<td style="padding: 12px 10px; color: ${o.direction === 'up' ? 'var(--up-color)' : 'var(--down-color)'}; font-weight: 700; text-transform: uppercase;">${o.direction === 'up' ? (lang === 'zh' ? '买涨' : 'UP') : (lang === 'zh' ? '买跌' : 'DOWN')}</td>
|
||||
<td style="padding: 12px 10px;">${parseFloat(o.amount).toFixed(2)}</td>
|
||||
<td style="padding: 12px 10px; font-family: 'Roboto Mono';">${parseFloat(o.opening_price).toLocaleString()}</td>
|
||||
<td style="padding: 12px 10px; font-family: 'Roboto Mono';">${o.closing_price ? parseFloat(o.closing_price).toLocaleString() : '--'}</td>
|
||||
<td style="padding: 12px 10px;"><span style="background: rgba(255,255,255,0.05); padding: 3px 8px; border-radius: 4px; font-size: 11px;">${o.status === 'pending' ? (lang === 'zh' ? '进行中' : 'pending') : (lang === 'zh' ? '已结算' : 'settled')}</span></td>
|
||||
<td style="padding: 12px 10px; text-align: right; color: ${o.profit > 0 ? 'var(--up-color)' : (o.profit < 0 ? 'var(--down-color)' : 'white')}; font-weight: 700;">
|
||||
${o.status === 'completed' ? (o.profit > 0 ? '+' : '') + parseFloat(o.profit).toFixed(2) : '--'}
|
||||
</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
} else { tbody.innerHTML = '<tr><td colspan="8" style="text-align: center; padding: 40px;">暂无记录</td></tr>'; }
|
||||
</tr>
|
||||
`).join('');
|
||||
} else {
|
||||
tbody.innerHTML = `<tr><td colspan="8" style="text-align: center; padding: 40px; color: var(--text-secondary);"><?php echo __('no_records'); ?></td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
function switchTab(btn, tab) {
|
||||
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
btn.style.borderBottom = '2px solid var(--accent-color)';
|
||||
btn.style.color = 'var(--accent-color)';
|
||||
document.querySelectorAll('.tab-btn').forEach(b => {
|
||||
b.style.color = 'var(--text-secondary)'; b.style.borderBottom = 'none';
|
||||
if (b !== btn) {
|
||||
b.style.borderBottom = 'none';
|
||||
b.style.color = 'var(--text-secondary)';
|
||||
}
|
||||
});
|
||||
btn.style.color = 'var(--accent-color)'; btn.style.borderBottom = '2px solid var(--accent-color)';
|
||||
activeTab = tab; fetchOrders();
|
||||
activeTab = tab;
|
||||
fetchOrders();
|
||||
}
|
||||
|
||||
fetchOrders(); setInterval(fetchOrders, 3000);
|
||||
document.getElementById('market-search').addEventListener('input', function(e) {
|
||||
const q = e.target.value.toUpperCase();
|
||||
document.querySelectorAll('.pair-item').forEach(item => {
|
||||
const text = item.querySelector('div div').innerText;
|
||||
item.style.display = text.includes(q) ? 'flex' : 'none';
|
||||
});
|
||||
});
|
||||
|
||||
fetchOrders();
|
||||
setInterval(fetchOrders, 3000);
|
||||
</script>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
331
spot.php
331
spot.php
@ -27,81 +27,91 @@ if ($user_id) {
|
||||
--input-bg: #1e2329;
|
||||
}
|
||||
|
||||
body { background-color: var(--bg-color); color: var(--text-primary); font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; margin: 0; overflow-y: auto !important; }
|
||||
body { background-color: var(--bg-color); color: var(--text-primary); font-family: 'Inter', 'PingFang SC', sans-serif; margin: 0; overflow-y: auto !important; }
|
||||
|
||||
.trading-layout { display: flex; gap: 1px; background: var(--border-color); padding: 0; min-height: calc(100vh - 64px); }
|
||||
.panel { background: var(--panel-bg); display: flex; flex-direction: column; }
|
||||
|
||||
/* Market Panel */
|
||||
.market-panel { width: 280px; flex-shrink: 0; border-right: 1px solid var(--border-color); }
|
||||
#pairs-list { height: 600px; overflow-y: auto; }
|
||||
.pair-item { display: flex; justify-content: space-between; padding: 10px 12px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.02); }
|
||||
.pair-item.active { background: rgba(240, 185, 11, 0.1); }
|
||||
.market-panel { width: 300px; flex-shrink: 0; border-right: 1px solid var(--border-color); }
|
||||
#pairs-list { height: calc(100vh - 120px); overflow-y: auto; scrollbar-width: thin; }
|
||||
.pair-item { display: flex; align-items: center; padding: 10px 16px; cursor: pointer; border-bottom: 1px solid rgba(255,255,255,0.02); transition: 0.2s; }
|
||||
.pair-item:hover { background: rgba(255,255,255,0.05); }
|
||||
.pair-item.active { background: rgba(240, 185, 11, 0.08); border-left: 3px solid var(--accent-color); }
|
||||
.pair-icon { width: 24px; height: 24px; margin-right: 12px; border-radius: 50%; }
|
||||
|
||||
/* Center Panel */
|
||||
.center-panel { flex: 1; background: var(--bg-color); display: flex; flex-direction: column; }
|
||||
.info-bar { height: 60px; display: flex; align-items: center; padding: 0 15px; gap: 15px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); flex-wrap: wrap; }
|
||||
.chart-container { height: 450px; background: var(--bg-color); border-bottom: 1px solid var(--border-color); }
|
||||
.order-placement-panel { display: flex; gap: 20px; padding: 20px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); }
|
||||
.center-panel { flex: 1; background: var(--bg-color); display: flex; flex-direction: column; min-width: 0; }
|
||||
.info-bar { height: 66px; display: flex; align-items: center; padding: 0 20px; gap: 25px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); }
|
||||
.chart-container { height: 550px; background: var(--bg-color); border-bottom: 1px solid var(--border-color); }
|
||||
.order-placement-panel { display: flex; gap: 30px; padding: 25px; border-bottom: 1px solid var(--border-color); background: var(--panel-bg); }
|
||||
.order-side-column { flex: 1; }
|
||||
|
||||
/* Input Styles */
|
||||
.input-row { background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 4px; display: flex; align-items: center; margin-bottom: 10px; padding: 8px 12px; }
|
||||
.input-row input { flex: 1; background: transparent; border: none; color: white; text-align: right; outline: none; font-size: 14px; }
|
||||
.execute-btn { width: 100%; padding: 12px; border: none; border-radius: 6px; font-weight: bold; font-size: 15px; cursor: pointer; color: white; }
|
||||
.input-row { background: var(--input-bg); border: 1px solid var(--border-color); border-radius: 6px; display: flex; align-items: center; margin-bottom: 12px; padding: 10px 15px; transition: 0.2s; }
|
||||
.input-row:focus-within { border-color: var(--accent-color); }
|
||||
.input-row input { flex: 1; background: transparent; border: none; color: white; text-align: right; outline: none; font-size: 14px; font-weight: 600; }
|
||||
.execute-btn { width: 100%; padding: 14px; border: none; border-radius: 8px; font-weight: bold; font-size: 16px; cursor: pointer; color: white; transition: 0.3s; margin-top: 10px; }
|
||||
.execute-btn:hover { opacity: 0.9; transform: translateY(-1px); }
|
||||
|
||||
/* Order Book Panel */
|
||||
.order-book-panel { width: 300px; flex-shrink: 0; border-left: 1px solid var(--border-color); }
|
||||
.ob-row { display: flex; justify-content: space-between; padding: 4px 15px; font-size: 12px; position: relative; }
|
||||
.order-book-panel { width: 320px; flex-shrink: 0; border-left: 1px solid var(--border-color); display: flex; flex-direction: column; }
|
||||
.ob-header { padding: 12px 16px; font-size: 12px; color: var(--text-secondary); border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; font-weight: 600; }
|
||||
.ob-row { display: flex; justify-content: space-between; padding: 4px 16px; font-size: 12px; position: relative; font-family: 'Roboto Mono', monospace; cursor: pointer; }
|
||||
.ob-row:hover { background: rgba(255,255,255,0.05); }
|
||||
.ob-vol-bar { position: absolute; top: 0; right: 0; bottom: 0; z-index: 0; opacity: 0.15; transition: width 0.3s; }
|
||||
|
||||
/* Tabs */
|
||||
.tab-btn { background: none; border: none; color: var(--text-secondary); padding: 15px 20px; font-size: 14px; font-weight: 600; cursor: pointer; position: relative; transition: 0.2s; }
|
||||
.tab-btn.active { color: var(--accent-color); }
|
||||
.tab-btn.active::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 3px; background: var(--accent-color); border-radius: 3px 3px 0 0; }
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 1400px) {
|
||||
.market-panel { width: 260px; }
|
||||
.order-book-panel { width: 280px; }
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.market-panel { display: none; }
|
||||
.order-book-panel { width: 250px; }
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.trading-layout { flex-direction: column; }
|
||||
.order-book-panel { width: 100%; border-left: none; border-top: 1px solid var(--border-color); }
|
||||
.chart-container { height: 350px; }
|
||||
.info-bar { height: auto; padding: 10px 15px; }
|
||||
.order-placement-panel { flex-direction: column; }
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.chart-container { height: 300px; }
|
||||
.info-bar-stats { display: none !important; }
|
||||
.order-side-column:not(:first-child) { margin-top: 20px; border-top: 1px solid var(--border-color); padding-top: 20px; }
|
||||
.chart-container { height: 400px; }
|
||||
.info-bar { height: auto; padding: 15px; flex-wrap: wrap; gap: 15px; }
|
||||
.order-placement-panel { flex-direction: column; gap: 40px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="trading-layout">
|
||||
<!-- Left Panel (Hidden on mobile) -->
|
||||
<!-- Left Panel (Market Pairs) -->
|
||||
<div class="panel market-panel">
|
||||
<div style="padding: 12px; border-bottom: 1px solid var(--border-color);">
|
||||
<div style="padding: 15px; border-bottom: 1px solid var(--border-color);">
|
||||
<div style="position: relative;">
|
||||
<i class="fas fa-search" style="position: absolute; left: 10px; top: 10px; color: var(--text-secondary);"></i>
|
||||
<input type="text" id="market-search" placeholder="搜索币对" style="width: 100%; background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 8px 12px 8px 32px; border-radius: 6px; font-size: 13px; outline: none;">
|
||||
<i class="fas fa-search" style="position: absolute; left: 12px; top: 12px; color: var(--text-secondary); font-size: 14px;"></i>
|
||||
<input type="text" id="market-search" placeholder="<?php echo __('search_pair'); ?>" style="width: 100%; background: var(--input-bg); border: 1px solid var(--border-color); color: white; padding: 10px 12px 10px 35px; border-radius: 8px; font-size: 13px; outline: none;">
|
||||
</div>
|
||||
</div>
|
||||
<div id="pairs-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- Center Panel -->
|
||||
<!-- Center Panel (Chart & Trading) -->
|
||||
<div class="panel center-panel">
|
||||
<div class="info-bar">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<img id="current-logo" src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" width="28" height="28" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<span id="current-pair-display" style="font-size: 18px; font-weight: bold;">BTC/USDT</span>
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<img id="current-logo" src="https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" width="32" height="32" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<span id="current-pair-display" style="font-size: 20px; font-weight: 800; letter-spacing: -0.5px;">BTC/USDT</span>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column;">
|
||||
<span id="last-price" style="font-size: 18px; font-weight: bold; color: var(--up-color);">--</span>
|
||||
<span id="price-change" style="font-size: 12px; color: var(--up-color);">--</span>
|
||||
<span id="last-price" style="font-size: 18px; font-weight: 700; color: var(--up-color); font-family: 'Roboto Mono', monospace;">--</span>
|
||||
<span id="price-change" style="font-size: 12px; color: var(--up-color); font-weight: 600;">--</span>
|
||||
</div>
|
||||
<div class="info-bar-stats" style="display: flex; gap: 20px; margin-left: auto; font-size: 11px;">
|
||||
<div style="color: var(--text-secondary);">24h高 <span id="high-24h" style="color: white; display: block;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h低 <span id="low-24h" style="color: white; display: block;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h量 <span id="vol-24h" style="color: white; display: block;">--</span></div>
|
||||
<div class="info-bar-stats desktop-only" style="display: flex; gap: 30px; margin-left: auto; font-size: 12px;">
|
||||
<div style="color: var(--text-secondary);">24h High <span id="high-24h" style="color: white; display: block; margin-top: 4px; font-weight: 600;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h Low <span id="low-24h" style="color: white; display: block; margin-top: 4px; font-weight: 600;">--</span></div>
|
||||
<div style="color: var(--text-secondary);">24h Vol <span id="vol-24h" style="color: white; display: block; margin-top: 4px; font-weight: 600;">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -113,103 +123,103 @@ if ($user_id) {
|
||||
<div class="order-placement-panel">
|
||||
<!-- Buy Column -->
|
||||
<div class="order-side-column" id="buy-column">
|
||||
<div style="display: flex; gap: 15px; margin-bottom: 15px;">
|
||||
<button class="order-type-btn" onclick="setOrderType('buy', 'limit')" id="buy-limit-btn" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 14px; padding: 0;">限价</button>
|
||||
<button class="order-type-btn active" onclick="setOrderType('buy', 'market')" id="buy-market-btn" style="background: none; border: none; color: var(--accent-color); font-weight: bold; cursor: pointer; font-size: 14px; padding: 0;">市价</button>
|
||||
<div style="display: flex; gap: 20px; margin-bottom: 20px;">
|
||||
<button class="order-type-btn" onclick="setOrderType('buy', 'limit')" id="buy-limit-btn" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 15px; font-weight: 700; padding: 0;"><?php echo __('limit'); ?></button>
|
||||
<button class="order-type-btn active" onclick="setOrderType('buy', 'market')" id="buy-market-btn" style="background: none; border: none; color: var(--accent-color); font-weight: 700; cursor: pointer; font-size: 15px; padding: 0;"><?php echo __('market'); ?></button>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 8px;">
|
||||
<span style="color: var(--text-secondary);">可用 <span id="buy-available">--</span> USDT</span>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 10px;">
|
||||
<span style="color: var(--text-secondary);"><?php echo __('available'); ?> <span id="buy-available" style="color: white; font-weight: 600;">--</span> USDT</span>
|
||||
</div>
|
||||
<div class="input-row" id="buy-price-row" style="display: none;">
|
||||
<span style="color: var(--text-secondary); font-size: 13px;">价格</span>
|
||||
<span style="color: var(--text-secondary); font-size: 13px; font-weight: 600;"><?php echo __('price'); ?></span>
|
||||
<input type="number" id="buy-price" placeholder="0.00">
|
||||
<span style="color: var(--text-secondary); font-size: 12px; margin-left: 5px;">USDT</span>
|
||||
<span style="color: var(--text-secondary); font-size: 12px; margin-left: 8px; font-weight: 600;">USDT</span>
|
||||
</div>
|
||||
<div class="input-row" id="buy-market-price-row">
|
||||
<span style="color: var(--text-secondary); font-size: 13px;">价格</span>
|
||||
<input type="text" id="buy-market-price-display" value="以当前市价买入" disabled style="text-align: right; color: var(--text-secondary);">
|
||||
<span style="color: var(--text-secondary); font-size: 13px; font-weight: 600;"><?php echo __('price'); ?></span>
|
||||
<input type="text" value="<?php echo __('market'); ?>" disabled style="text-align: right; color: var(--text-secondary);">
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<span style="color: var(--text-secondary); font-size: 13px;">数量</span>
|
||||
<span style="color: var(--text-secondary); font-size: 13px; font-weight: 600;"><?php echo __('amount'); ?></span>
|
||||
<input type="number" id="buy-amount" placeholder="0.00">
|
||||
<span class="asset-name" style="color: var(--text-secondary); font-size: 12px; margin-left: 5px; width: 40px; text-align: right;">BTC</span>
|
||||
<span class="asset-name" style="color: var(--text-secondary); font-size: 12px; margin-left: 8px; width: 45px; text-align: right; font-weight: 600;">BTC</span>
|
||||
</div>
|
||||
|
||||
<div style="margin: 15px 0 25px 0; position: relative; padding: 0 5px;">
|
||||
<input type="range" min="0" max="100" value="0" id="buy-slider" style="width: 100%; accent-color: var(--up-color);" oninput="updateFromSlider('buy', this.value)">
|
||||
<div style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 10px; color: var(--text-secondary);">
|
||||
<span onclick="setSlider('buy', 0)">0%</span>
|
||||
<span onclick="setSlider('buy', 25)">25%</span>
|
||||
<span onclick="setSlider('buy', 50)">50%</span>
|
||||
<span onclick="setSlider('buy', 75)">75%</span>
|
||||
<span onclick="setSlider('buy', 100)">100%</span>
|
||||
<div style="margin: 20px 0 30px 0; position: relative; padding: 0 5px;">
|
||||
<input type="range" min="0" max="100" value="0" id="buy-slider" style="width: 100%; accent-color: var(--up-color); cursor: pointer;" oninput="updateFromSlider('buy', this.value)">
|
||||
<div style="display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: var(--text-secondary); font-weight: 500;">
|
||||
<span onclick="setSlider('buy', 0)" style="cursor: pointer;">0%</span>
|
||||
<span onclick="setSlider('buy', 25)" style="cursor: pointer;">25%</span>
|
||||
<span onclick="setSlider('buy', 50)" style="cursor: pointer;">50%</span>
|
||||
<span onclick="setSlider('buy', 75)" style="cursor: pointer;">75%</span>
|
||||
<span onclick="setSlider('buy', 100)" style="cursor: pointer;">100%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="execute-btn" style="background: var(--up-color);" onclick="placeOrder('buy')">买入 <span class="asset-name">BTC</span></button>
|
||||
<button class="execute-btn" style="background: var(--up-color);" onclick="placeOrder('buy')"><?php echo __('buy'); ?> <span class="asset-name">BTC</span></button>
|
||||
</div>
|
||||
|
||||
<!-- Sell Column -->
|
||||
<div class="order-side-column" id="sell-column">
|
||||
<div style="display: flex; gap: 15px; margin-bottom: 15px;">
|
||||
<button class="order-type-btn active" onclick="setOrderType('sell', 'limit')" id="sell-limit-btn" style="background: none; border: none; color: var(--accent-color); font-weight: bold; cursor: pointer; font-size: 14px; padding: 0;">限价</button>
|
||||
<button class="order-type-btn" onclick="setOrderType('sell', 'market')" id="sell-market-btn" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 14px; padding: 0;">市价</button>
|
||||
<div style="display: flex; gap: 20px; margin-bottom: 20px;">
|
||||
<button class="order-type-btn active" onclick="setOrderType('sell', 'limit')" id="sell-limit-btn" style="background: none; border: none; color: var(--accent-color); font-weight: 700; cursor: pointer; font-size: 15px; padding: 0;"><?php echo __('limit'); ?></button>
|
||||
<button class="order-type-btn" onclick="setOrderType('sell', 'market')" id="sell-market-btn" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; font-size: 15px; font-weight: 700; padding: 0;"><?php echo __('market'); ?></button>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 8px;">
|
||||
<span style="color: var(--text-secondary);">可用 <span id="sell-available">--</span> <span class="asset-name">BTC</span></span>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 10px;">
|
||||
<span style="color: var(--text-secondary);"><?php echo __('available'); ?> <span id="sell-available" style="color: white; font-weight: 600;">--</span> <span class="asset-name">BTC</span></span>
|
||||
</div>
|
||||
<div class="input-row" id="sell-price-row">
|
||||
<span style="color: var(--text-secondary); font-size: 13px;">价格</span>
|
||||
<span style="color: var(--text-secondary); font-size: 13px; font-weight: 600;"><?php echo __('price'); ?></span>
|
||||
<input type="number" id="sell-price" placeholder="0.00">
|
||||
<span style="color: var(--text-secondary); font-size: 12px; margin-left: 5px;">USDT</span>
|
||||
<span style="color: var(--text-secondary); font-size: 12px; margin-left: 8px; font-weight: 600;">USDT</span>
|
||||
</div>
|
||||
<div class="input-row" id="sell-market-price-row" style="display: none;">
|
||||
<span style="color: var(--text-secondary); font-size: 13px;">价格</span>
|
||||
<input type="text" id="sell-market-price-display" value="以当前市价卖出" disabled style="text-align: right; color: var(--text-secondary);">
|
||||
<span style="color: var(--text-secondary); font-size: 13px; font-weight: 600;"><?php echo __('price'); ?></span>
|
||||
<input type="text" value="<?php echo __('market'); ?>" disabled style="text-align: right; color: var(--text-secondary);">
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<span style="color: var(--text-secondary); font-size: 13px;">数量</span>
|
||||
<span style="color: var(--text-secondary); font-size: 13px; font-weight: 600;"><?php echo __('amount'); ?></span>
|
||||
<input type="number" id="sell-amount" placeholder="0.00">
|
||||
<span class="asset-name" style="color: var(--text-secondary); font-size: 12px; margin-left: 5px; width: 40px; text-align: right;">BTC</span>
|
||||
<span class="asset-name" style="color: var(--text-secondary); font-size: 12px; margin-left: 8px; width: 45px; text-align: right; font-weight: 600;">BTC</span>
|
||||
</div>
|
||||
|
||||
<div style="margin: 15px 0 25px 0; position: relative; padding: 0 5px;">
|
||||
<input type="range" min="0" max="100" value="0" id="sell-slider" style="width: 100%; accent-color: var(--down-color);" oninput="updateFromSlider('sell', this.value)">
|
||||
<div style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 10px; color: var(--text-secondary);">
|
||||
<span onclick="setSlider('sell', 0)">0%</span>
|
||||
<span onclick="setSlider('sell', 25)">25%</span>
|
||||
<span onclick="setSlider('sell', 50)">50%</span>
|
||||
<span onclick="setSlider('sell', 75)">75%</span>
|
||||
<span onclick="setSlider('sell', 100)">100%</span>
|
||||
<div style="margin: 20px 0 30px 0; position: relative; padding: 0 5px;">
|
||||
<input type="range" min="0" max="100" value="0" id="sell-slider" style="width: 100%; accent-color: var(--down-color); cursor: pointer;" oninput="updateFromSlider('sell', this.value)">
|
||||
<div style="display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: var(--text-secondary); font-weight: 500;">
|
||||
<span onclick="setSlider('sell', 0)" style="cursor: pointer;">0%</span>
|
||||
<span onclick="setSlider('sell', 25)" style="cursor: pointer;">25%</span>
|
||||
<span onclick="setSlider('sell', 50)" style="cursor: pointer;">50%</span>
|
||||
<span onclick="setSlider('sell', 75)" style="cursor: pointer;">75%</span>
|
||||
<span onclick="setSlider('sell', 100)" style="cursor: pointer;">100%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="execute-btn" style="background: var(--down-color);" onclick="placeOrder('sell')">卖出 <span class="asset-name">BTC</span></button>
|
||||
<button class="execute-btn" style="background: var(--down-color);" onclick="placeOrder('sell')"><?php echo __('sell'); ?> <span class="asset-name">BTC</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Orders Table -->
|
||||
<div style="background: var(--panel-bg);">
|
||||
<div style="display: flex; border-bottom: 1px solid var(--border-color); padding: 0 15px;">
|
||||
<button class="tab-btn active" onclick="switchTab(this, 'open')" style="background: none; border: none; color: var(--accent-color); padding: 12px 15px; font-size: 14px; border-bottom: 2px solid var(--accent-color); cursor: pointer;">当前委托</button>
|
||||
<button class="tab-btn" onclick="switchTab(this, 'history')" style="background: none; border: none; color: var(--text-secondary); padding: 12px 15px; font-size: 14px; cursor: pointer;">历史委托</button>
|
||||
<div style="display: flex; border-bottom: 1px solid var(--border-color); padding: 0 10px;">
|
||||
<button class="tab-btn active" onclick="switchTab(this, 'open')"><?php echo __('open_orders'); ?></button>
|
||||
<button class="tab-btn" onclick="switchTab(this, 'history')"><?php echo __('order_history'); ?></button>
|
||||
</div>
|
||||
<div style="padding: 15px; overflow-x: auto;">
|
||||
<table id="orders-table" style="width: 100%; border-collapse: collapse; min-width: 600px; font-size: 12px;">
|
||||
<thead style="color: var(--text-secondary); text-align: left;">
|
||||
<table id="orders-table" style="width: 100%; border-collapse: collapse; min-width: 800px; font-size: 13px;">
|
||||
<thead style="color: var(--text-secondary); text-align: left; background: rgba(255,255,255,0.02);">
|
||||
<tr>
|
||||
<th style="padding: 10px 5px;">时间</th>
|
||||
<th style="padding: 10px 5px;">币对</th>
|
||||
<th style="padding: 10px 5px;">类型</th>
|
||||
<th style="padding: 10px 5px;">方向</th>
|
||||
<th style="padding: 10px 5px;">价格</th>
|
||||
<th style="padding: 10px 5px;">数量</th>
|
||||
<th style="padding: 10px 5px;">状态</th>
|
||||
<th style="padding: 10px 5px; text-align: right;">操作</th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('time'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('pair'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('type'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('direction'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('price'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('amount'); ?></th>
|
||||
<th style="padding: 12px 10px;"><?php echo __('status'); ?></th>
|
||||
<th style="padding: 12px 10px; text-align: right;"><?php echo __('action'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="orders-tbody">
|
||||
<tr><td colspan="8" style="text-align: center; padding: 40px; color: var(--text-secondary);">暂无记录</td></tr>
|
||||
<tr><td colspan="8" style="text-align: center; padding: 60px; color: var(--text-secondary); font-size: 14px;"><?php echo __('no_records'); ?></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -219,15 +229,15 @@ if ($user_id) {
|
||||
|
||||
<!-- Right Panel (Order Book) -->
|
||||
<div class="panel order-book-panel">
|
||||
<div style="padding: 10px 15px; font-size: 12px; color: var(--text-secondary); border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between;">
|
||||
<span>价格(USDT)</span>
|
||||
<span>数量(BTC)</span>
|
||||
<div class="ob-header">
|
||||
<span>Price(USDT)</span>
|
||||
<span>Amount(<span class="asset-name">BTC</span>)</span>
|
||||
</div>
|
||||
<div id="asks-list" style="display: flex; flex-direction: column-reverse;"></div>
|
||||
<div style="padding: 10px 15px; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); text-align: center;">
|
||||
<div id="ob-mid-price" style="font-size: 16px; font-weight: bold;">--</div>
|
||||
<div id="asks-list" style="display: flex; flex-direction: column-reverse; flex: 1; overflow: hidden;"></div>
|
||||
<div style="padding: 15px; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); text-align: center; background: rgba(255,255,255,0.01);">
|
||||
<div id="ob-mid-price" style="font-size: 18px; font-weight: 800; font-family: 'Roboto Mono', monospace;">--</div>
|
||||
</div>
|
||||
<div id="bids-list"></div>
|
||||
<div id="bids-list" style="flex: 1; overflow: hidden;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -240,14 +250,16 @@ if ($user_id) {
|
||||
let marketData = {};
|
||||
let orderTypes = { buy: 'market', sell: 'limit' };
|
||||
let activeTab = 'open';
|
||||
const lang = '<?php echo $lang; ?>';
|
||||
|
||||
const pairs = [
|
||||
'BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT', 'ADAUSDT', 'DOGEUSDT', 'DOTUSDT', 'LINKUSDT', 'AVAXUSDT'
|
||||
'BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT', 'XRPUSDT', 'ADAUSDT', 'AVAXUSDT', 'DOGEUSDT', 'DOTUSDT', 'LINKUSDT',
|
||||
'MATICUSDT', 'NEARUSDT', 'LTCUSDT', 'ATOMUSDT', 'UNIUSDT', 'XLMUSDT', 'ALGOUSDT', 'TRXUSDT', 'BCHUSDT', 'SHIBUSDT'
|
||||
];
|
||||
|
||||
function initChart(symbol) {
|
||||
new TradingView.widget({
|
||||
"width": "100%", "height": "100%", "symbol": "BINANCE:" + symbol, "interval": "15", "theme": "dark", "style": "1", "locale": "zh_CN", "container_id": "tv_chart_container", "backgroundColor": "#0b0e11", "hide_side_toolbar": true, "allow_symbol_change": false, "save_image": false
|
||||
"width": "100%", "height": "100%", "symbol": "BINANCE:" + symbol, "interval": "15", "theme": "dark", "style": "1", "locale": lang === 'zh' ? 'zh_CN' : 'en', "container_id": "tv_chart_container", "backgroundColor": "#0b0e11", "hide_side_toolbar": true, "allow_symbol_change": false, "save_image": false
|
||||
});
|
||||
}
|
||||
initChart(currentPair);
|
||||
@ -271,6 +283,7 @@ if ($user_id) {
|
||||
document.getElementById('last-price').style.color = data.P >= 0 ? 'var(--up-color)' : 'var(--down-color)';
|
||||
document.getElementById('price-change').innerText = (data.P >= 0 ? '+' : '') + data.P + '%';
|
||||
document.getElementById('ob-mid-price').innerText = currentPrice.toLocaleString();
|
||||
document.getElementById('ob-mid-price').style.color = data.P >= 0 ? 'var(--up-color)' : 'var(--down-color)';
|
||||
document.getElementById('high-24h').innerText = parseFloat(data.h).toLocaleString();
|
||||
document.getElementById('low-24h').innerText = parseFloat(data.l).toLocaleString();
|
||||
document.getElementById('vol-24h').innerText = parseFloat(data.v).toLocaleString();
|
||||
@ -285,10 +298,18 @@ if ($user_id) {
|
||||
pairs.forEach(p => {
|
||||
const d = marketData[p] || {c: 0, P: 0};
|
||||
const name = p.replace('USDT', '');
|
||||
const icon = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png`;
|
||||
html += `
|
||||
<div class="pair-item ${currentPair === p ? 'active' : ''}" onclick="switchPair('${p}')">
|
||||
<span style="font-weight: 500;">${name}/USDT</span>
|
||||
<span style="color: ${d.P >= 0 ? 'var(--up-color)' : 'var(--down-color)'}">${parseFloat(d.c).toLocaleString()}</span>
|
||||
<img src="${icon}" class="pair-icon" onerror="this.src='https://cdn-icons-png.flaticon.com/512/2585/2585274.png'">
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; font-size: 14px;">${name}/USDT</div>
|
||||
<div style="font-size: 11px; color: var(--text-secondary);">Vol ${parseFloat(d.v || 0).toLocaleString()}</div>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<div style="font-weight: 600; font-family: 'Roboto Mono', monospace; font-size: 13px;">${parseFloat(d.c).toLocaleString()}</div>
|
||||
<div style="color: ${d.P >= 0 ? 'var(--up-color)' : 'var(--down-color)'}; font-size: 11px; font-weight: 600;">${(d.P >= 0 ? '+' : '') + d.P}%</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
@ -296,10 +317,12 @@ if ($user_id) {
|
||||
}
|
||||
|
||||
function switchPair(p) {
|
||||
if (currentPair === p) return;
|
||||
currentPair = p;
|
||||
const name = p.replace('USDT', '');
|
||||
document.getElementById('current-pair-display').innerText = name + '/USDT';
|
||||
document.querySelectorAll('.asset-name').forEach(el => el.innerText = name);
|
||||
document.getElementById('current-logo').src = `https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/${name.toLowerCase()}.png`;
|
||||
initChart(p);
|
||||
updateAvailable();
|
||||
}
|
||||
@ -328,15 +351,46 @@ if ($user_id) {
|
||||
const asks = document.getElementById('asks-list');
|
||||
const bids = document.getElementById('bids-list');
|
||||
let asksHtml = ''; let bidsHtml = '';
|
||||
for(let i=0; i<10; i++) {
|
||||
const ap = currentPrice * (1 + (i+1)*0.001);
|
||||
const bp = currentPrice * (1 - (i+1)*0.001);
|
||||
asksHtml += `<div class="ob-row"><span style="color: var(--down-color);">${ap.toFixed(2)}</span><span>${(Math.random()).toFixed(4)}</span></div>`;
|
||||
bidsHtml += `<div class="ob-row"><span style="color: var(--up-color);">${bp.toFixed(2)}</span><span>${(Math.random()).toFixed(4)}</span></div>`;
|
||||
let maxVol = 0;
|
||||
const rows = 18;
|
||||
const askData = [];
|
||||
const bidData = [];
|
||||
|
||||
for(let i=0; i<rows; i++) {
|
||||
const av = Math.random() * 2 + 0.1;
|
||||
const bv = Math.random() * 2 + 0.1;
|
||||
askData.push(av);
|
||||
bidData.push(bv);
|
||||
maxVol = Math.max(maxVol, av, bv);
|
||||
}
|
||||
|
||||
for(let i=0; i<rows; i++) {
|
||||
const ap = currentPrice * (1 + (i+1)*0.0002);
|
||||
const bp = currentPrice * (1 - (i+1)*0.0002);
|
||||
const av = askData[i];
|
||||
const bv = bidData[i];
|
||||
|
||||
asksHtml += `
|
||||
<div class="ob-row" onclick="setPrice(${ap.toFixed(2)})">
|
||||
<div class="ob-vol-bar" style="width: ${(av/maxVol*100)}%; background: var(--down-color);"></div>
|
||||
<span style="color: var(--down-color); font-weight: 600; z-index: 1;">${ap.toFixed(2)}</span>
|
||||
<span style="color: white; opacity: 0.9; z-index: 1;">${av.toFixed(4)}</span>
|
||||
</div>`;
|
||||
bidsHtml += `
|
||||
<div class="ob-row" onclick="setPrice(${bp.toFixed(2)})">
|
||||
<div class="ob-vol-bar" style="width: ${(bv/maxVol*100)}%; background: var(--up-color);"></div>
|
||||
<span style="color: var(--up-color); font-weight: 600; z-index: 1;">${bp.toFixed(2)}</span>
|
||||
<span style="color: white; opacity: 0.9; z-index: 1;">${bv.toFixed(4)}</span>
|
||||
</div>`;
|
||||
}
|
||||
asks.innerHTML = asksHtml; bids.innerHTML = bidsHtml;
|
||||
}
|
||||
|
||||
function setPrice(p) {
|
||||
if (orderTypes.buy === 'limit') document.getElementById('buy-price').value = p;
|
||||
if (orderTypes.sell === 'limit') document.getElementById('sell-price').value = p;
|
||||
}
|
||||
|
||||
function setSlider(side, val) {
|
||||
document.getElementById(side + '-slider').value = val;
|
||||
updateFromSlider(side, val);
|
||||
@ -345,7 +399,9 @@ if ($user_id) {
|
||||
function updateFromSlider(side, val) {
|
||||
const coin = currentPair.replace('USDT', '');
|
||||
if (side === 'buy') {
|
||||
const amount = (usdtBalance * (val/100)) / (parseFloat(document.getElementById('buy-price').value) || currentPrice);
|
||||
const price = orderTypes['buy'] === 'limit' ? parseFloat(document.getElementById('buy-price').value) : currentPrice;
|
||||
if (!price) return;
|
||||
const amount = (usdtBalance * (val/100)) / price;
|
||||
document.getElementById('buy-amount').value = amount.toFixed(6);
|
||||
} else {
|
||||
const amount = (userAssets[coin] || 0) * (val/100);
|
||||
@ -355,9 +411,10 @@ if ($user_id) {
|
||||
|
||||
async function placeOrder(side) {
|
||||
const amount = parseFloat(document.getElementById(side + '-amount').value);
|
||||
if (!amount) return alert('请输入数量');
|
||||
if (!amount || amount <= 0) return alert(lang === 'zh' ? '请输入有效数量' : 'Please enter a valid amount');
|
||||
const price = orderTypes[side] === 'limit' ? parseFloat(document.getElementById(side + '-price').value) : currentPrice;
|
||||
|
||||
if (orderTypes[side] === 'limit' && (!price || price <= 0)) return alert(lang === 'zh' ? '请输入有效价格' : 'Please enter a valid price');
|
||||
|
||||
const resp = await fetch('api/place_order.php', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
@ -367,7 +424,11 @@ if ($user_id) {
|
||||
})
|
||||
});
|
||||
const res = await resp.json();
|
||||
if (res.success) { alert('成功'); updateAvailable(); fetchOrders(); } else { alert(res.error); }
|
||||
if (res.success) {
|
||||
alert(lang === 'zh' ? '下单成功' : 'Order Placed Successfully');
|
||||
updateAvailable();
|
||||
fetchOrders();
|
||||
} else { alert(res.error); }
|
||||
}
|
||||
|
||||
async function fetchOrders() {
|
||||
@ -377,36 +438,50 @@ if ($user_id) {
|
||||
if (res.success && res.data.length > 0) {
|
||||
tbody.innerHTML = res.data.map(o => `
|
||||
<tr style="border-bottom: 1px solid var(--border-color);">
|
||||
<td style="padding: 10px 5px;">${o.created_at}</td>
|
||||
<td style="padding: 10px 5px; font-weight: bold;">${o.symbol}</td>
|
||||
<td style="padding: 10px 5px;">${o.order_type}</td>
|
||||
<td style="padding: 10px 5px; color: ${o.side === 'buy' ? 'var(--up-color)' : 'var(--down-color)'}">${o.side}</td>
|
||||
<td style="padding: 10px 5px;">${parseFloat(o.price).toLocaleString()}</td>
|
||||
<td style="padding: 10px 5px;">${parseFloat(o.amount).toFixed(6)}</td>
|
||||
<td style="padding: 10px 5px;">${o.status}</td>
|
||||
<td style="padding: 10px 5px; text-align: right;">${o.status === 'open' ? `<button onclick="cancelOrder(${o.id})">取消</button>` : '--'}</td>
|
||||
<td style="padding: 15px 10px;">${o.created_at}</td>
|
||||
<td style="padding: 15px 10px; font-weight: 700;">${o.symbol}</td>
|
||||
<td style="padding: 15px 10px; text-transform: capitalize;">${o.order_type}</td>
|
||||
<td style="padding: 15px 10px; color: ${o.side === 'buy' ? 'var(--up-color)' : 'var(--down-color)'}; font-weight: 700; text-transform: uppercase;">${o.side}</td>
|
||||
<td style="padding: 15px 10px; font-family: 'Roboto Mono', monospace;">${parseFloat(o.price).toLocaleString()}</td>
|
||||
<td style="padding: 15px 10px; font-family: 'Roboto Mono', monospace;">${parseFloat(o.amount).toFixed(6)}</td>
|
||||
<td style="padding: 15px 10px;"><span style="background: rgba(255,255,255,0.05); padding: 4px 10px; border-radius: 4px; font-size: 11px;">${o.status}</span></td>
|
||||
<td style="padding: 15px 10px; text-align: right;">${o.status === 'open' ? `<button onclick="cancelOrder(${o.id})" style="background: var(--danger-color); color: white; border: none; padding: 5px 12px; border-radius: 4px; cursor: pointer; font-size: 12px;"><?php echo __('cancel'); ?></button>` : '--'}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} else {
|
||||
tbody.innerHTML = '<tr><td colspan="8" style="text-align: center; padding: 40px;">暂无记录</td></tr>';
|
||||
tbody.innerHTML = `<tr><td colspan="8" style="text-align: center; padding: 60px; color: var(--text-secondary); font-size: 14px;"><?php echo __('no_records'); ?></td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
function switchTab(btn, tab) {
|
||||
document.querySelectorAll('.tab-btn').forEach(b => {
|
||||
b.classList.remove('active');
|
||||
b.style.color = 'var(--text-secondary)';
|
||||
b.style.borderBottom = 'none';
|
||||
async function cancelOrder(id) {
|
||||
if (!confirm(lang === 'zh' ? '确定要取消此订单吗?' : 'Are you sure you want to cancel this order?')) return;
|
||||
const resp = await fetch('api/cancel_order.php', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({id: id})
|
||||
});
|
||||
const res = await resp.json();
|
||||
if (res.success) { fetchOrders(); updateAvailable(); } else { alert(res.error); }
|
||||
}
|
||||
|
||||
function switchTab(btn, tab) {
|
||||
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
btn.style.color = 'var(--accent-color)';
|
||||
btn.style.borderBottom = '2px solid var(--accent-color)';
|
||||
activeTab = tab;
|
||||
fetchOrders();
|
||||
}
|
||||
|
||||
document.getElementById('market-search').addEventListener('input', function(e) {
|
||||
const q = e.target.value.toUpperCase();
|
||||
document.querySelectorAll('.pair-item').forEach(item => {
|
||||
const text = item.querySelector('div div').innerText;
|
||||
item.style.display = text.includes(q) ? 'flex' : 'none';
|
||||
});
|
||||
});
|
||||
|
||||
updateAvailable();
|
||||
fetchOrders();
|
||||
setInterval(fetchOrders, 5000);
|
||||
</script>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
Loading…
x
Reference in New Issue
Block a user