jiema
This commit is contained in:
parent
d7eac0da6a
commit
1af2cf25db
271
admin.php
271
admin.php
@ -4,7 +4,6 @@ require_once __DIR__ . '/db/config.php';
|
||||
|
||||
$pdo = db();
|
||||
|
||||
// Ensure user is admin
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
@ -19,7 +18,6 @@ if ($user['role'] !== 'admin') {
|
||||
|
||||
$action = $_GET['action'] ?? 'dashboard';
|
||||
|
||||
// Handle Actions
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if ($action === 'confirm_recharge') {
|
||||
$id = $_POST['id'];
|
||||
@ -38,208 +36,241 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$id = $_POST['id'];
|
||||
$stmt = $pdo->prepare("UPDATE recharges SET status = 'rejected' WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
} elseif ($action === 'reply_support') {
|
||||
$user_id = $_POST['user_id'];
|
||||
$message = $_POST['message'];
|
||||
$stmt = $pdo->prepare("INSERT INTO support_messages (user_id, sender, message) VALUES (?, 'admin', ?)");
|
||||
$stmt->execute([$user_id, $message]);
|
||||
} elseif ($action === 'update_settings') {
|
||||
foreach ($_POST['settings'] as $key => $value) {
|
||||
$stmt = $pdo->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = ?");
|
||||
$stmt->execute([$value, $key]);
|
||||
$stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = ?");
|
||||
$stmt->execute([$key, $value, $value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Data
|
||||
$stats = [
|
||||
'users' => $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn(),
|
||||
'pending_recharges' => $pdo->query("SELECT COUNT(*) FROM recharges WHERE status = 'pending'")->fetchColumn(),
|
||||
'total_orders' => $pdo->query("SELECT COUNT(*) FROM sms_orders")->fetchColumn(),
|
||||
'total_balance' => $pdo->query("SELECT SUM(balance) FROM users")->fetchColumn(),
|
||||
];
|
||||
|
||||
$pending_recharges = $pdo->query("SELECT r.*, u.username FROM recharges r JOIN users u ON r.user_id = u.id WHERE r.status = 'pending' ORDER BY r.created_at DESC")->fetchAll();
|
||||
$support_requests = $pdo->query("SELECT m.*, u.username FROM support_messages m JOIN users u ON m.user_id = u.id WHERE m.sender = 'user' AND m.id IN (SELECT MAX(id) FROM support_messages GROUP BY user_id) ORDER BY m.created_at DESC")->fetchAll();
|
||||
$settings = $pdo->query("SELECT * FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
$settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>管理后台 - 全球接码</title>
|
||||
<title>管理后台 - <?= htmlspecialchars($settings['site_name'] ?? '全球接码') ?></title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #ff4d94;
|
||||
--bg-light: #fff5f7;
|
||||
--surface-light: #ffffff;
|
||||
--text-main: #2d1a1e;
|
||||
--text-muted: #8a6d71;
|
||||
--border-color: #ffd1dc;
|
||||
--primary: #3b82f6;
|
||||
--bg-body: #f8fafc;
|
||||
--surface: #ffffff;
|
||||
--text-main: #0f172a;
|
||||
--text-muted: #64748b;
|
||||
--border-color: #e2e8f0;
|
||||
}
|
||||
body { background-color: var(--bg-light); font-family: 'Plus Jakarta Sans', sans-serif; }
|
||||
body { background-color: var(--bg-body); font-family: 'Plus Jakarta Sans', sans-serif; color: var(--text-main); font-size: 14px; }
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
width: 260px;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
background: var(--surface-light);
|
||||
border-right: 2px solid var(--border-color);
|
||||
color: var(--text-main);
|
||||
padding: 30px 20px;
|
||||
background: var(--surface);
|
||||
border-right: 1px solid var(--border-color);
|
||||
padding: 40px 24px;
|
||||
box-shadow: 1px 0 0 rgba(0,0,0,0.02);
|
||||
}
|
||||
.main { margin-left: 250px; padding: 40px; }
|
||||
.main { margin-left: 260px; padding: 50px; }
|
||||
.nav-link {
|
||||
color: var(--text-muted);
|
||||
color: #475569;
|
||||
font-weight: 600;
|
||||
border-radius: 12px;
|
||||
border-radius: 14px;
|
||||
margin-bottom: 8px;
|
||||
transition: all 0.3s;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 18px;
|
||||
}
|
||||
.nav-link:hover, .nav-link.active {
|
||||
background-color: var(--primary-color);
|
||||
.nav-link:hover { background-color: #f1f5f9; color: var(--primary); }
|
||||
.nav-link.active {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(255, 77, 148, 0.2);
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.25);
|
||||
}
|
||||
.card {
|
||||
background-color: var(--surface-light);
|
||||
border: 2px solid var(--border-color);
|
||||
.stat-card {
|
||||
background-color: var(--surface);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 20px;
|
||||
box-shadow: 6px 6px 0px var(--border-color);
|
||||
padding: 24px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.stat-card:hover { transform: translateY(-4px); }
|
||||
.card {
|
||||
background-color: var(--surface);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 24px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.btn-primary { background-color: var(--primary-color); border: none; border-radius: 10px; }
|
||||
.btn-primary:hover { background-color: #ff1a75; }
|
||||
.form-control { border: 2px solid var(--border-color); border-radius: 10px; }
|
||||
.form-control:focus { border-color: var(--primary-color); box-shadow: none; }
|
||||
.table { color: var(--text-main); }
|
||||
.btn-primary { background-color: var(--primary); border: none; border-radius: 12px; padding: 12px 24px; font-weight: 700; }
|
||||
.form-control { border: 1.5px solid var(--border-color); border-radius: 12px; padding: 12px 16px; background: #f8fafc; font-weight: 500; }
|
||||
.form-control:focus { border-color: var(--primary); background: #fff; box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.08); }
|
||||
|
||||
.table thead th {
|
||||
background: #f8fafc;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
padding: 15px 20px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="sidebar">
|
||||
<h4 class="fw-bold text-primary mb-4"><i class="fas fa-shield-alt me-2"></i>管理中心</h4>
|
||||
<div class="d-flex align-items-center gap-3 mb-5 px-1">
|
||||
<div class="bg-primary text-white rounded-circle d-flex align-items-center justify-content-center" style="width: 44px; height: 44px;">
|
||||
<i class="fas fa-user-shield"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold fs-5">ADMIN</div>
|
||||
<div class="small text-muted fw-bold" style="font-size: 10px;">CONTROL PANEL</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="nav flex-column">
|
||||
<a class="nav-link <?= $action === 'dashboard' ? 'active' : '' ?>" href="?action=dashboard"><i class="fas fa-chart-pie me-2"></i> 数据概览</a>
|
||||
<a class="nav-link <?= $action === 'recharges' ? 'active' : '' ?>" href="?action=recharges"><i class="fas fa-receipt me-2"></i> 充值审核</a>
|
||||
<a class="nav-link <?= $action === 'support' ? 'active' : '' ?>" href="?action=support"><i class="fas fa-comments me-2"></i> 客服消息</a>
|
||||
<a class="nav-link <?= $action === 'settings' ? 'active' : '' ?>" href="?action=settings"><i class="fas fa-tools me-2"></i> 系统参数</a>
|
||||
<hr class="text-muted">
|
||||
<a class="nav-link" href="dashboard.php"><i class="fas fa-external-link-alt me-2"></i> 回到前台</a>
|
||||
<a class="nav-link <?= $action === 'dashboard' ? 'active' : '' ?>" href="?action=dashboard"><i class="fas fa-chart-line"></i> 数据概览</a>
|
||||
<a class="nav-link <?= $action === 'recharges' ? 'active' : '' ?>" href="?action=recharges"><i class="fas fa-wallet"></i> 充值审核</a>
|
||||
<a class="nav-link <?= $action === 'settings' ? 'active' : '' ?>" href="?action=settings"><i class="fas fa-cog"></i> 系统设置</a>
|
||||
<hr class="text-muted opacity-10 my-4">
|
||||
<a class="nav-link" href="dashboard.php" style="color: #64748b;"><i class="fas fa-reply"></i> 返回前台系统</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div class="d-flex justify-content-between align-items-center mb-5">
|
||||
<div class="mb-5">
|
||||
<h2 class="fw-bold"><?= [
|
||||
'dashboard' => '数据大盘',
|
||||
'recharges' => '充值申请列表',
|
||||
'support' => '用户咨询回复',
|
||||
'settings' => '全局系统设置'
|
||||
'dashboard' => '核心数据概览',
|
||||
'recharges' => '充值审核中心',
|
||||
'settings' => '系统全局参数配置'
|
||||
][$action] ?></h2>
|
||||
<div class="text-muted small">系统时间: <?= date('Y-m-d H:i') ?></div>
|
||||
</div>
|
||||
|
||||
<?php if ($action === 'dashboard'): ?>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card p-4 text-center">
|
||||
<div class="text-muted mb-2">注册用户总量</div>
|
||||
<h2 class="fw-bold text-primary"><?= $stats['users'] ?></h2>
|
||||
<div class="row g-4">
|
||||
<div class="col-md-3">
|
||||
<div class="stat-card">
|
||||
<div class="text-muted small fw-bold mb-1">注册用户总量</div>
|
||||
<h2 class="fw-bold text-primary mb-0"><?= number_format($stats['users']) ?></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card p-4 text-center">
|
||||
<div class="text-muted mb-2">待审核充值</div>
|
||||
<h2 class="fw-bold text-warning"><?= $stats['pending_recharges'] ?></h2>
|
||||
<div class="col-md-3">
|
||||
<div class="stat-card">
|
||||
<div class="text-muted small fw-bold mb-1">待审核充值</div>
|
||||
<h2 class="fw-bold text-warning mb-0"><?= number_format($stats['pending_recharges']) ?></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card p-4 text-center">
|
||||
<div class="text-muted mb-2">累计成交订单</div>
|
||||
<h2 class="fw-bold text-success"><?= $stats['total_orders'] ?></h2>
|
||||
<div class="col-md-3">
|
||||
<div class="stat-card">
|
||||
<div class="text-muted small fw-bold mb-1">累计接码订单</div>
|
||||
<h2 class="fw-bold text-success mb-0"><?= number_format($stats['total_orders']) ?></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="stat-card">
|
||||
<div class="text-muted small fw-bold mb-1">系统用户总余额</div>
|
||||
<h2 class="fw-bold text-dark mb-0">$<?= number_format($stats['total_balance'], 2) ?></h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif ($action === 'recharges'): ?>
|
||||
<div class="card p-4">
|
||||
<div class="card p-0 overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<table class="table align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>用户名</th>
|
||||
<th>申请金额</th>
|
||||
<th>交易 TXID</th>
|
||||
<th>提交时间</th>
|
||||
<th>操作决策</th>
|
||||
<th class="ps-4">用户信息 / USER</th>
|
||||
<th>申请金额 / AMOUNT</th>
|
||||
<th>交易 TXID / HASH</th>
|
||||
<th>提交时间 / TIME</th>
|
||||
<th class="text-end pe-4">管理操作 / ACTION</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($pending_recharges as $r): ?>
|
||||
<tr>
|
||||
<td class="fw-bold"><?= htmlspecialchars($r['username']) ?></td>
|
||||
<td class="text-success fw-bold">$<?= $r['amount'] ?></td>
|
||||
<td><code class="small text-muted"><?= htmlspecialchars($r['txid']) ?></code></td>
|
||||
<td class="small"><?= $r['created_at'] ?></td>
|
||||
<td>
|
||||
<form method="POST" action="?action=confirm_recharge" class="d-inline">
|
||||
<td class="ps-4">
|
||||
<div class="fw-bold text-dark"><?= htmlspecialchars($r['username']) ?></div>
|
||||
<div class="small text-muted">USER_ID: <?= $r['user_id'] ?></div>
|
||||
</td>
|
||||
<td><span class="fw-bold text-primary fs-5">$<?= number_format($r['amount'], 2) ?></span></td>
|
||||
<td><code class="small text-muted bg-light p-2 rounded"><?= htmlspecialchars($r['txid']) ?></code></td>
|
||||
<td class="small text-muted fw-medium"><?= $r['created_at'] ?></td>
|
||||
<td class="text-end pe-4">
|
||||
<form method="POST" action="?action=confirm_recharge" class="d-inline" onsubmit="return confirm('确认审核通过?')">
|
||||
<input type="hidden" name="id" value="<?= $r['id'] ?>">
|
||||
<button class="btn btn-sm btn-success px-3">通过</button>
|
||||
<button class="btn btn-sm btn-success px-4 rounded-pill fw-bold">通过</button>
|
||||
</form>
|
||||
<form method="POST" action="?action=reject_recharge" class="d-inline">
|
||||
<form method="POST" action="?action=reject_recharge" class="d-inline" onsubmit="return confirm('确认驳回?')">
|
||||
<input type="hidden" name="id" value="<?= $r['id'] ?>">
|
||||
<button class="btn btn-sm btn-outline-danger px-3">驳回</button>
|
||||
<button class="btn btn-sm btn-outline-danger px-4 rounded-pill fw-bold ms-2">驳回</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($pending_recharges)): ?>
|
||||
<tr><td colspan="5" class="text-center py-4 text-muted">暂无待处理充值</td></tr>
|
||||
<tr><td colspan="5" class="text-center py-5 text-muted fw-bold">目前暂无任何待处理的充值申请</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif ($action === 'support'): ?>
|
||||
<div class="row">
|
||||
<?php foreach ($support_requests as $s): ?>
|
||||
<div class="col-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between mb-3">
|
||||
<h5 class="fw-bold mb-0 text-primary"><?= htmlspecialchars($s['username']) ?></h5>
|
||||
<span class="small text-muted"><?= $s['created_at'] ?></span>
|
||||
</div>
|
||||
<div class="p-3 rounded-3 mb-4" style="background-color: var(--bg-light); border: 1px solid var(--border-color);">
|
||||
<?= htmlspecialchars($s['message']) ?>
|
||||
</div>
|
||||
<form method="POST" action="?action=reply_support">
|
||||
<input type="hidden" name="user_id" value="<?= $s['user_id'] ?>">
|
||||
<div class="input-group">
|
||||
<input type="text" name="message" class="form-control" placeholder="输入回复内容..." required>
|
||||
<button class="btn btn-primary px-4">发送回复</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($support_requests)): ?>
|
||||
<div class="col-12 text-center py-5 text-muted">暂无待回复消息</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php elseif ($action === 'settings'): ?>
|
||||
<div class="card p-4">
|
||||
<div class="card">
|
||||
<form method="POST" action="?action=update_settings">
|
||||
<div class="row">
|
||||
<?php foreach ($settings as $key => $val): ?>
|
||||
<div class="col-md-6 mb-4">
|
||||
<label class="form-label fw-bold"><?= $key ?></label>
|
||||
<input type="text" name="settings[<?= $key ?>]" value="<?= htmlspecialchars($val) ?>" class="form-control p-3">
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold small text-muted">网站显示名称 / SITE NAME</label>
|
||||
<input type="text" name="settings[site_name]" value="<?= htmlspecialchars($settings['site_name'] ?? '全球接码') ?>" class="form-control">
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold small text-muted">网站 Logo 路径 / LOGO PATH</label>
|
||||
<input type="text" name="settings[site_logo]" value="<?= htmlspecialchars($settings['site_logo'] ?? 'assets/pasted-20260210-082628-83f66727.png') ?>" class="form-control">
|
||||
</div>
|
||||
<div class="text-end mt-4">
|
||||
<button class="btn btn-primary btn-lg px-5">保存所有系统参数</button>
|
||||
<div class="col-12">
|
||||
<label class="form-label fw-bold small text-muted">系统公告内容 (支持 HTML) / ANNOUNCEMENT</label>
|
||||
<textarea name="settings[notice_text]" class="form-control" rows="4"><?= htmlspecialchars($settings['notice_text'] ?? '') ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="col-12 my-5"><div class="border-top"></div></div>
|
||||
|
||||
<h5 class="fw-bold mb-3"><i class="fas fa-wallet text-primary me-2"></i> 区块链支付钱包地址配置 / CRYPTO WALLETS</h5>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold small text-muted">USDT TRC20 收款地址</label>
|
||||
<input type="text" name="settings[usdt_trc20_address]" value="<?= htmlspecialchars($settings['usdt_trc20_address'] ?? '') ?>" class="form-control" placeholder="T...">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold small text-muted">USDT ERC20 收款地址</label>
|
||||
<input type="text" name="settings[usdt_erc20_address]" value="<?= htmlspecialchars($settings['usdt_erc20_address'] ?? '') ?>" class="form-control" placeholder="0x...">
|
||||
</div>
|
||||
|
||||
<div class="col-12 my-5"><div class="border-top"></div></div>
|
||||
|
||||
<h5 class="fw-bold mb-3"><i class="fas fa-plug text-primary me-2"></i> LUBAN SMS API 后端配置 / API GATEWAY</h5>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-bold small text-muted">LUBAN SMS API KEY</label>
|
||||
<input type="password" name="settings[lubansms_apikey]" value="<?= htmlspecialchars($settings['lubansms_apikey'] ?? '') ?>" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-end mt-5 pt-3">
|
||||
<button class="btn btn-primary btn-lg px-5 shadow">应用所有配置项</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -3,6 +3,9 @@ session_start();
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/api/LocalLubanApi.php';
|
||||
|
||||
// Price multiplier to earn profit (User requested 1.5 - 2x)
|
||||
const PRICE_MULTIPLIER = 1.8;
|
||||
|
||||
$pdo = db();
|
||||
$api = new LubanSMS();
|
||||
|
||||
@ -15,6 +18,39 @@ if (!isset($_SESSION['user_id']) && $action !== 'login') {
|
||||
exit;
|
||||
}
|
||||
|
||||
function check_trc20_payment($address, $target_amount, $order_time) {
|
||||
if (!$address || $address == 'TEm1B...TRC20_ADDRESS_HERE') return false;
|
||||
|
||||
// TronScan API to check transactions
|
||||
$url = "https://apilist.tronscan.org/api/token_trc20/transfers?limit=20&start=0&direction=1&address=" . urlencode($address);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if (!$response) return false;
|
||||
$data = json_decode($response, true);
|
||||
if (!isset($data['token_transfers'])) return false;
|
||||
|
||||
foreach ($data['token_transfers'] as $tx) {
|
||||
if ($tx['symbol'] !== 'USDT') continue;
|
||||
|
||||
$amount = (float)$tx['quant'] / pow(10, $tx['tokenInfo']['tokenDecimal']);
|
||||
$tx_time = (int)($tx['block_ts'] / 1000);
|
||||
$order_ts = strtotime($order_time);
|
||||
|
||||
// Match amount (with small tolerance for floating point) and time (must be after order)
|
||||
if (abs($amount - $target_amount) < 0.001 && $tx_time > $order_ts) {
|
||||
return $tx['transaction_id'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'get_balance':
|
||||
$stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ?");
|
||||
@ -24,13 +60,31 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 'get_countries':
|
||||
echo json_encode($api->getCountries());
|
||||
$res = $api->getCountries();
|
||||
if ($res['code'] === 0 && isset($res['msg'])) {
|
||||
$res['data'] = $res['msg'];
|
||||
unset($res['msg']);
|
||||
}
|
||||
echo json_encode($res);
|
||||
break;
|
||||
|
||||
case 'get_services':
|
||||
$country = $_GET['country'] ?? '';
|
||||
$service = $_GET['service'] ?? '';
|
||||
$res = $api->getServices($country, $service);
|
||||
|
||||
if ($res['code'] === 0 && isset($res['msg'])) {
|
||||
$res['data'] = $res['msg'];
|
||||
unset($res['msg']);
|
||||
}
|
||||
|
||||
if ($res['code'] === 0 && isset($res['data'])) {
|
||||
foreach ($res['data'] as &$item) {
|
||||
if (isset($item['cost'])) {
|
||||
$item['cost'] = round($item['cost'] * PRICE_MULTIPLIER, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode($res);
|
||||
break;
|
||||
|
||||
@ -38,7 +92,7 @@ switch ($action) {
|
||||
$service_id = $_GET['service_id'] ?? '';
|
||||
$country_name = $_GET['country_name'] ?? '未知国家';
|
||||
$service_name = $_GET['service_name'] ?? '未知项目';
|
||||
$price = (float)($_GET['price'] ?? 1.0);
|
||||
$price = (float)($_GET['price'] ?? 0);
|
||||
|
||||
if (!$service_id) {
|
||||
echo json_encode(['code' => 400, 'msg' => 'Service ID is required']);
|
||||
@ -61,7 +115,6 @@ switch ($action) {
|
||||
$stmt = $pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ?");
|
||||
$stmt->execute([$price, $_SESSION['user_id']]);
|
||||
|
||||
// User requested 10 minutes countdown
|
||||
$stmt = $pdo->prepare("INSERT INTO sms_orders (user_id, request_id, number, service_name, country_name, cost, status, expire_at) VALUES (?, ?, ?, ?, ?, ?, 'pending', DATE_ADD(NOW(), INTERVAL 10 MINUTE))");
|
||||
$stmt->execute([$_SESSION['user_id'], $res['request_id'], $res['number'], $service_name, $country_name, $price]);
|
||||
$pdo->commit();
|
||||
@ -93,7 +146,6 @@ switch ($action) {
|
||||
case 'release_number':
|
||||
$request_id = $_GET['request_id'] ?? '';
|
||||
|
||||
// Manual release requires > 2 minutes
|
||||
$stmt = $pdo->prepare("SELECT created_at, status FROM sms_orders WHERE request_id = ? AND user_id = ?");
|
||||
$stmt->execute([$request_id, $_SESSION['user_id']]);
|
||||
$order = $stmt->fetch();
|
||||
@ -110,7 +162,7 @@ switch ($action) {
|
||||
|
||||
$createdAt = strtotime($order['created_at']);
|
||||
if (time() - $createdAt < 120) {
|
||||
echo json_encode(['code' => 400, 'msg' => '获取号码不足2分钟,暂时无法手动释放。请稍候或等待系统自动释放。']);
|
||||
echo json_encode(['code' => 400, 'msg' => '获取号码不足2分钟,暂时无法手动释放。']);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -123,7 +175,6 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 'get_active_orders':
|
||||
// Auto-expire orders
|
||||
$stmt = $pdo->prepare("UPDATE sms_orders SET status = 'expired' WHERE status = 'pending' AND expire_at < NOW()");
|
||||
$stmt->execute();
|
||||
|
||||
@ -139,9 +190,6 @@ switch ($action) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Add random decimal to help identify payment (e.g. 10.42)
|
||||
// If it already has decimals, we might want to keep it or refine it.
|
||||
// The user said "any recharge add decimal".
|
||||
$base = floor($amount);
|
||||
$random_decimal = rand(1, 99) / 100;
|
||||
$final_amount = $base + $random_decimal;
|
||||
@ -169,26 +217,26 @@ switch ($action) {
|
||||
|
||||
if ($recharge['status'] === 'completed') {
|
||||
echo json_encode(['code' => 0, 'status' => 'completed']);
|
||||
break;
|
||||
exit;
|
||||
}
|
||||
|
||||
// SIMULATION: In a real app, this would query a blockchain API for the address.
|
||||
// For testing, we'll auto-complete after 15 seconds.
|
||||
$createdAt = strtotime($recharge['created_at']);
|
||||
if (time() - $createdAt > 15) {
|
||||
// Try Auto-Detection
|
||||
$settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
$trc20_address = $settings['usdt_trc20_address'] ?? '';
|
||||
|
||||
$txid = check_trc20_payment($trc20_address, $recharge['amount'], $recharge['created_at']);
|
||||
if ($txid) {
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
$stmt = $pdo->prepare("UPDATE recharges SET status = 'completed' WHERE id = ?");
|
||||
$stmt->execute([$recharge_id]);
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE recharges SET status = 'completed', txid = ? WHERE id = ?");
|
||||
$stmt->execute([$txid, $recharge_id]);
|
||||
$stmt = $pdo->prepare("UPDATE users SET balance = balance + ? WHERE id = ?");
|
||||
$stmt->execute([$recharge['amount'], $_SESSION['user_id']]);
|
||||
|
||||
$stmt->execute([$recharge['amount'], $recharge['user_id']]);
|
||||
$pdo->commit();
|
||||
echo json_encode(['code' => 0, 'status' => 'completed']);
|
||||
} catch (Exception $e) {
|
||||
$pdo->rollBack();
|
||||
echo json_encode(['code' => 500, 'msg' => 'Database error']);
|
||||
echo json_encode(['code' => 500, 'msg' => 'Detection error']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['code' => 0, 'status' => 'pending']);
|
||||
|
||||
BIN
assets/pasted-20260210-074218-c408deaa.png
Normal file
BIN
assets/pasted-20260210-074218-c408deaa.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
BIN
assets/pasted-20260210-074819-9c0ead1f.png
Normal file
BIN
assets/pasted-20260210-074819-9c0ead1f.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/pasted-20260210-075800-30a55110.png
Normal file
BIN
assets/pasted-20260210-075800-30a55110.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
BIN
assets/pasted-20260210-080314-97487350.png
Normal file
BIN
assets/pasted-20260210-080314-97487350.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
BIN
assets/pasted-20260210-082628-83f66727.png
Normal file
BIN
assets/pasted-20260210-082628-83f66727.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 290 KiB |
850
dashboard.php
850
dashboard.php
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,10 @@
|
||||
<?php
|
||||
$current_page = basename($_SERVER['PHP_SELF']);
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
$pdo_sidebar = db();
|
||||
$settings_sidebar = $pdo_sidebar->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
$site_name = $settings_sidebar['site_name'] ?? '全球接码';
|
||||
$site_logo = $settings_sidebar['site_logo'] ?? 'assets/pasted-20260210-082628-83f66727.png';
|
||||
?>
|
||||
<style>
|
||||
.sidebar {
|
||||
@ -8,53 +13,100 @@ $current_page = basename($_SERVER['PHP_SELF']);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: #ffffff;
|
||||
border-right: 2px solid #ffd1dc;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
backdrop-filter: blur(10px);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.05);
|
||||
z-index: 1000;
|
||||
padding: 2rem 1.5rem;
|
||||
padding: 2rem 1.2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.sidebar-brand {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
color: #ff4d94;
|
||||
text-decoration: none;
|
||||
margin-bottom: 3rem;
|
||||
padding: 0.5rem 1rem;
|
||||
margin-bottom: 2.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
gap: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.sidebar-brand img {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 12px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
.sidebar-brand span {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, #1a1a1a 0%, #4a4a4a 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.sidebar .nav-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
color: #8a6d71;
|
||||
gap: 14px;
|
||||
padding: 12px 18px;
|
||||
color: #64748b;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
border-radius: 14px;
|
||||
margin-bottom: 6px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.sidebar .nav-link i {
|
||||
font-size: 1.2rem;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
.sidebar .nav-link:hover {
|
||||
background-color: #f8fafc;
|
||||
color: #0f172a;
|
||||
transform: translateX(4px);
|
||||
}
|
||||
.sidebar .nav-link:hover i {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.sidebar .nav-link.active {
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
||||
color: #ffffff;
|
||||
box-shadow: 0 4px 15px rgba(37, 99, 235, 0.25);
|
||||
}
|
||||
.sidebar .nav-link.active i {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.user-profile-mini {
|
||||
background: #f8fafc;
|
||||
border-radius: 16px;
|
||||
margin-bottom: 8px;
|
||||
transition: all 0.2s;
|
||||
padding: 16px;
|
||||
margin-top: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
border: 1px solid #f1f5f9;
|
||||
}
|
||||
.sidebar .nav-link:hover, .sidebar .nav-link.active {
|
||||
background-color: #fff8f9;
|
||||
color: #ff4d94;
|
||||
.logout-link {
|
||||
color: #ef4444 !important;
|
||||
}
|
||||
.logout-link:hover {
|
||||
background-color: #fef2f2 !important;
|
||||
}
|
||||
.sidebar .nav-link i { font-size: 1.2rem; }
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.sidebar { width: 80px; padding: 2rem 0.5rem; align-items: center; }
|
||||
.sidebar-brand span, .sidebar .nav-link span { display: none; }
|
||||
.sidebar-brand { margin-bottom: 2rem; justify-content: center; }
|
||||
.sidebar .nav-link { justify-content: center; padding: 12px; }
|
||||
.sidebar { width: 85px; padding: 2rem 0.8rem; }
|
||||
.sidebar-brand span, .sidebar .nav-link span, .user-profile-mini { display: none; }
|
||||
.sidebar-brand { margin-bottom: 2rem; padding: 0; justify-content: center; }
|
||||
.sidebar .nav-link { justify-content: center; padding: 15px; margin-bottom: 10px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="sidebar">
|
||||
<a href="dashboard.php" class="sidebar-brand">
|
||||
<i class="fas fa-bolt"></i>
|
||||
<span>全球接码</span>
|
||||
<img src="<?= htmlspecialchars($site_logo) ?>?v=<?= time() ?>" alt="Logo">
|
||||
<span><?= htmlspecialchars($site_name) ?></span>
|
||||
</a>
|
||||
|
||||
<nav class="flex-grow-1">
|
||||
@ -63,7 +115,7 @@ $current_page = basename($_SERVER['PHP_SELF']);
|
||||
<span>工作台</span>
|
||||
</a>
|
||||
<a href="orders.php" class="nav-link <?= $current_page === 'orders.php' ? 'active' : '' ?>">
|
||||
<i class="fas fa-history"></i>
|
||||
<i class="fas fa-receipt"></i>
|
||||
<span>接码记录</span>
|
||||
</a>
|
||||
<a href="recharge.php" class="nav-link <?= $current_page === 'recharge.php' ? 'active' : '' ?>">
|
||||
@ -78,12 +130,19 @@ $current_page = basename($_SERVER['PHP_SELF']);
|
||||
|
||||
<div class="mt-auto">
|
||||
<?php if (isset($user['username'])): ?>
|
||||
<div class="p-3 bg-light rounded-4 mb-3 d-none d-lg-block">
|
||||
<div class="small text-muted fw-bold mb-1">当前用户</div>
|
||||
<div class="fw-bold text-truncate"><?= htmlspecialchars($user['username']) ?></div>
|
||||
<div class="user-profile-mini">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="rounded-circle bg-primary d-flex align-items-center justify-content-center text-white fw-bold" style="width: 32px; height: 32px; font-size: 0.8rem;">
|
||||
<?= strtoupper(substr($user['username'], 0, 1)) ?>
|
||||
</div>
|
||||
<div class="overflow-hidden">
|
||||
<div class="small text-muted fw-bold">Hi, <?= htmlspecialchars($user['username']) ?></div>
|
||||
<div class="small fw-bold text-primary">$<?= number_format($user['balance'] ?? 0, 2) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<a href="auth.php?action=logout" class="nav-link text-danger">
|
||||
<a href="auth.php?action=logout" class="nav-link logout-link">
|
||||
<i class="fas fa-sign-out-alt"></i>
|
||||
<span>退出登录</span>
|
||||
</a>
|
||||
|
||||
463
index.php
463
index.php
@ -4,342 +4,249 @@ if (isset($_SESSION['user_id'])) {
|
||||
header('Location: dashboard.php');
|
||||
exit;
|
||||
}
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
$pdo = db();
|
||||
$settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
$site_name = $settings['site_name'] ?? '全球接码';
|
||||
$site_logo = $settings['site_logo'] ?? 'assets/pasted-20260210-082628-83f66727.png';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>全球接码 - 专业、安全、快速的验证码接收平台</title>
|
||||
<title><?= htmlspecialchars($site_name) ?> - 全球专业接码平台</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;700;800&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #ff4d94;
|
||||
--accent-color: #ff1a75;
|
||||
--bg-light: #fff5f7;
|
||||
--surface-light: #ffffff;
|
||||
--text-main: #2d1a1e;
|
||||
--text-muted: #8a6d71;
|
||||
--border-color: #ffd1dc;
|
||||
--primary: #3b82f6;
|
||||
--primary-gradient: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
||||
--bg-body: #f8fafc;
|
||||
--text-main: #1e293b;
|
||||
}
|
||||
body {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
background-color: var(--bg-light);
|
||||
background: #f8fafc;
|
||||
color: var(--text-main);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.navbar {
|
||||
background-color: rgba(255, 245, 247, 0.9);
|
||||
backdrop-filter: blur(10px);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding: 20px 0;
|
||||
overflow-x: hidden;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
padding: 160px 0 100px;
|
||||
background: radial-gradient(circle at top right, rgba(255, 77, 148, 0.1), transparent 40%),
|
||||
radial-gradient(circle at bottom left, rgba(255, 209, 220, 0.2), transparent 40%);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: radial-gradient(circle at 10% 20%, rgba(59, 130, 246, 0.05) 0%, rgba(59, 130, 246, 0) 50%);
|
||||
position: relative;
|
||||
}
|
||||
.hero-section::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; right: 0;
|
||||
width: 40%; height: 100%;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.03) 0%, rgba(59, 130, 246, 0) 100%);
|
||||
clip-path: polygon(25% 0%, 100% 0%, 100% 100%, 0% 100%);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.navbar-brand img { height: 40px; }
|
||||
|
||||
.hero-title {
|
||||
font-size: 4rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.1;
|
||||
margin-bottom: 24px;
|
||||
color: var(--text-main);
|
||||
margin-bottom: 1.5rem;
|
||||
letter-spacing: -2px;
|
||||
}
|
||||
.hero-title span {
|
||||
color: var(--primary-color);
|
||||
.hero-subtitle {
|
||||
font-size: 1.25rem;
|
||||
color: #64748b;
|
||||
margin-bottom: 2.5rem;
|
||||
max-width: 600px;
|
||||
}
|
||||
.glass-card {
|
||||
background-color: var(--surface-light);
|
||||
border: 2px solid var(--border-color);
|
||||
|
||||
.btn-main {
|
||||
padding: 18px 40px;
|
||||
font-weight: 800;
|
||||
border-radius: 18px;
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
.btn-main:hover { transform: translateY(-3px); box-shadow: 0 12px 30px rgba(59, 130, 246, 0.3); }
|
||||
|
||||
.form-card {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||
border-radius: 32px;
|
||||
padding: 40px;
|
||||
box-shadow: 10px 10px 0px var(--border-color);
|
||||
padding: 3rem;
|
||||
box-shadow: 0 40px 80px rgba(15, 23, 42, 0.05);
|
||||
}
|
||||
.feature-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background-color: rgba(255, 77, 148, 0.1);
|
||||
color: var(--primary-color);
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.input-group-custom {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
border: none;
|
||||
padding: 16px 32px;
|
||||
border-radius: 16px;
|
||||
.input-group-custom label {
|
||||
font-weight: 700;
|
||||
transition: all 0.3s ease;
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
color: #475569;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
padding-left: 4px;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: var(--accent-color);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 20px rgba(255, 77, 148, 0.3);
|
||||
color: white;
|
||||
}
|
||||
.form-control {
|
||||
background-color: #fff;
|
||||
border: 2px solid var(--border-color);
|
||||
color: var(--text-main);
|
||||
.input-group-custom .form-control {
|
||||
border: 1.5px solid #e2e8f0;
|
||||
border-radius: 16px;
|
||||
padding: 14px 20px;
|
||||
background: #fff;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.form-control:focus {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: none;
|
||||
.input-group-custom .form-control:focus {
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.08);
|
||||
}
|
||||
.footer {
|
||||
padding: 80px 0 40px;
|
||||
background-color: #ffffff;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
.step-number {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
|
||||
.stat-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
gap: 8px;
|
||||
background: #fff;
|
||||
padding: 10px 20px;
|
||||
border-radius: 100px;
|
||||
font-weight: 800;
|
||||
font-size: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.03);
|
||||
margin-bottom: 2rem;
|
||||
color: var(--primary);
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.hero-title { font-size: 2.5rem; }
|
||||
|
||||
.floating-shape {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
opacity: 0.1;
|
||||
filter: blur(2px);
|
||||
animation: float 6s ease-in-out infinite;
|
||||
}
|
||||
@keyframes float {
|
||||
0% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-20px); }
|
||||
100% { transform: translateY(0px); }
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.hero-title { font-size: 3rem; }
|
||||
.hero-section { text-align: center; padding-top: 100px; padding-bottom: 100px; }
|
||||
.hero-subtitle { margin-left: auto; margin-right: auto; }
|
||||
.form-card { margin-top: 3rem; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg fixed-top">
|
||||
<nav class="navbar navbar-expand-lg fixed-top py-4">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold fs-3" href="#" style="color: var(--primary-color);"><i class="fas fa-globe me-2"></i>全球接码</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto gap-3">
|
||||
<li class="nav-item"><a class="nav-link" href="#features">服务特性</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#how-it-works">使用说明</a></li>
|
||||
<li class="nav-item"><a class="btn btn-outline-dark px-4 rounded-pill" href="#" data-bs-toggle="modal" data-bs-target="#loginModal">登录</a></li>
|
||||
<li class="nav-item"><a class="btn btn-primary px-4 rounded-pill" href="#" data-bs-toggle="modal" data-bs-target="#registerModal">开始使用</a></li>
|
||||
</ul>
|
||||
<a class="navbar-brand fw-bold d-flex align-items-center gap-2" href="#">
|
||||
<img src="<?= htmlspecialchars($site_logo) ?>" alt="Logo">
|
||||
<span class="fs-4 fw-800" style="letter-spacing: -1px;"><?= htmlspecialchars($site_name) ?></span>
|
||||
</a>
|
||||
<div class="ms-auto">
|
||||
<a href="support.php" class="text-muted text-decoration-none fw-bold small me-4">联系客服</a>
|
||||
<button class="btn btn-outline-primary fw-bold rounded-pill px-4" data-bs-toggle="modal" data-bs-target="#loginModal">登入系统</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="hero-section">
|
||||
<div class="container">
|
||||
<div class="row align-items-center g-5">
|
||||
<div class="col-lg-7">
|
||||
<h1 class="hero-title">隐私第一,<br><span>全球号码</span> 随心接</h1>
|
||||
<p class="fs-5 text-muted mb-5">我们提供稳定、高效的全球虚拟号码验证码接收服务。支持 Telegram, WhatsApp, Facebook 等数千个社交平台。全自动收码,仅支持 USDT 支付,让您的隐私得到全方位保护。</p>
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-6">
|
||||
<div class="stat-badge">
|
||||
<i class="fas fa-signal"></i> 节点状态: 全球高可用实时连接
|
||||
</div>
|
||||
<h1 class="hero-title">
|
||||
专业接码<br><span class="text-primary">从未如此简单</span>
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
支持全球 200+ 国家和地区,对接数千个热门社交平台及服务项目。全自动 API 监听,USDT 秒级入账,为您业务保驾护航。
|
||||
</p>
|
||||
<div class="d-flex gap-3">
|
||||
<button class="btn btn-primary btn-lg px-5" data-bs-toggle="modal" data-bs-target="#registerModal">立即开启</button>
|
||||
<a href="#how-it-works" class="btn btn-outline-secondary btn-lg px-5">使用教程</a>
|
||||
<button class="btn btn-primary btn-main" data-bs-toggle="modal" data-bs-target="#registerModal">
|
||||
立即开启接码之旅 <i class="fas fa-rocket ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-5 d-flex gap-4">
|
||||
<div class="text-center">
|
||||
<h4 class="fw-bold mb-0">120+</h4>
|
||||
<p class="small text-muted">支持国家</p>
|
||||
</div>
|
||||
<div class="vr opacity-25"></div>
|
||||
<div class="text-center">
|
||||
<h4 class="fw-bold mb-0">2.5k+</h4>
|
||||
<p class="small text-muted">集成项目</p>
|
||||
</div>
|
||||
<div class="vr opacity-25"></div>
|
||||
<div class="text-center">
|
||||
<h4 class="fw-bold mb-0">秒级</h4>
|
||||
<p class="small text-muted">到码速度</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="glass-card">
|
||||
<h4 class="fw-bold mb-4 text-center">欢迎回来</h4>
|
||||
<form action="auth.php?action=login" method="POST">
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted">用户名</label>
|
||||
<input type="text" name="username" class="form-control" placeholder="输入您的用户名" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-muted">密码</label>
|
||||
<input type="password" name="password" class="form-control" placeholder="输入您的密码" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 py-3">进入工作台</button>
|
||||
</form>
|
||||
<p class="mt-4 text-center text-muted small">新用户? <a href="#" class="fw-bold" style="color: var(--primary-color);" data-bs-toggle="modal" data-bs-target="#registerModal">立即注册</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="py-5" id="how-it-works">
|
||||
<div class="container py-5">
|
||||
<div class="text-center mb-5">
|
||||
<h2 class="fw-bold fs-1">四步开启高效收码</h2>
|
||||
<p class="text-muted">简单易用的流程,助您快速获取验证码</p>
|
||||
</div>
|
||||
<div class="row g-4">
|
||||
<div class="col-md-3">
|
||||
<div class="mt-5 pt-4 d-flex gap-5 opacity-50">
|
||||
<div class="text-center">
|
||||
<div class="step-number mx-auto">1</div>
|
||||
<h5 class="fw-bold">注册账号</h5>
|
||||
<p class="small text-muted">创建一个属于您的匿名账号,仅需用户名和密码。</p>
|
||||
<div class="h3 fw-800 mb-0">200+</div>
|
||||
<div class="small fw-bold">国家地区</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<div class="step-number mx-auto">2</div>
|
||||
<h5 class="fw-bold">充值余额</h5>
|
||||
<p class="small text-muted">通过 USDT (TRC20/ERC20) 充值,金额实时到账。</p>
|
||||
<div class="h3 fw-800 mb-0">5000+</div>
|
||||
<div class="small fw-bold">日均项目</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<div class="step-number mx-auto">3</div>
|
||||
<h5 class="fw-bold">选取项目</h5>
|
||||
<p class="small text-muted">在控制面板选择目标国家和社交软件项目。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<div class="step-number mx-auto">4</div>
|
||||
<h5 class="fw-bold">接收短信</h5>
|
||||
<p class="small text-muted">获取号码后在对应 App 输入,网页自动刷新验证码。</p>
|
||||
<div class="h3 fw-800 mb-0">0.01s</div>
|
||||
<div class="small fw-bold">API 响应</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="py-5 bg-white" id="features">
|
||||
<div class="container py-5">
|
||||
<div class="row align-items-center g-5">
|
||||
<div class="col-lg-6">
|
||||
<h2 class="fw-bold fs-1 mb-4">为什么选择我们的服务?</h2>
|
||||
<div class="d-flex gap-4 mb-4">
|
||||
<div class="feature-icon flex-shrink-0"><i class="fas fa-microchip"></i></div>
|
||||
<div>
|
||||
<h5 class="fw-bold">AI 智能路由</h5>
|
||||
<p class="text-muted">自动选择最稳定的线路,确保高频率注册也能顺畅进行。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-4 mb-4">
|
||||
<div class="feature-icon flex-shrink-0"><i class="fas fa-lock"></i></div>
|
||||
<div>
|
||||
<h5 class="fw-bold">端到端隐私保护</h5>
|
||||
<p class="text-muted">不记录任何用户敏感信息,支付痕迹不可追踪。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-4">
|
||||
<div class="feature-icon flex-shrink-0"><i class="fas fa-comments"></i></div>
|
||||
<div>
|
||||
<h5 class="fw-bold">专业中文客服</h5>
|
||||
<p class="text-muted">7x24 小时在线支持,解决您在取码过程中的任何疑难。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<img src="https://images.pexels.com/photos/730547/pexels-photo-730547.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" alt="Security" class="img-fluid rounded-5 shadow-lg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="col-lg-5 offset-lg-1">
|
||||
<div class="form-card" id="authForm">
|
||||
<h3 class="fw-800 mb-2">快速加入</h3>
|
||||
<p class="text-muted small mb-4">创建账号即刻开始您的自动化业务流程</p>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-4">
|
||||
<h4 class="fw-bold mb-4" style="color: var(--primary-color);"><i class="fas fa-globe me-2"></i>全球接码</h4>
|
||||
<p class="text-muted">引领全球的隐私通讯解决方案。我们不仅提供号码,更提供安全感。</p>
|
||||
<form id="registerForm" onsubmit="handleAuth(event, 'register')">
|
||||
<div class="input-group-custom">
|
||||
<label>设置用户名</label>
|
||||
<input type="text" name="username" class="form-control" placeholder="输入 4-12 位英文字符" required>
|
||||
</div>
|
||||
<div class="col-lg-2 offset-lg-1">
|
||||
<h6 class="fw-bold mb-4">核心服务</h6>
|
||||
<ul class="list-unstyled d-flex flex-column gap-2">
|
||||
<li><a href="#" class="text-muted text-decoration-none">Telegram 取码</a></li>
|
||||
<li><a href="#" class="text-muted text-decoration-none">WhatsApp 注册</a></li>
|
||||
<li><a href="#" class="text-muted text-decoration-none">Facebook 验证</a></li>
|
||||
<li><a href="#" class="text-muted text-decoration-none">X (Twitter) 绑定</a></li>
|
||||
</ul>
|
||||
<div class="input-group-custom">
|
||||
<label>登录密码</label>
|
||||
<input type="password" name="password" class="form-control" placeholder="设置您的复杂密码" required>
|
||||
</div>
|
||||
<div class="col-lg-2">
|
||||
<h6 class="fw-bold mb-4">快速导航</h6>
|
||||
<ul class="list-unstyled d-flex flex-column gap-2">
|
||||
<li><a href="#" class="text-muted text-decoration-none">常见问题</a></li>
|
||||
<li><a href="#" class="text-muted text-decoration-none">API 文档</a></li>
|
||||
<li><a href="#" class="text-muted text-decoration-none">服务条款</a></li>
|
||||
</ul>
|
||||
<div class="input-group-custom">
|
||||
<label>确认密码</label>
|
||||
<input type="password" name="confirm_password" class="form-control" placeholder="再次确认您的密码" required>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<h6 class="fw-bold mb-4">关注动态</h6>
|
||||
<p class="text-muted small">加入我们的频道,获取最新号码上新通知。</p>
|
||||
<div class="d-flex gap-3 mt-3">
|
||||
<a href="#" class="text-muted fs-4"><i class="fab fa-telegram"></i></a>
|
||||
<a href="#" class="text-muted fs-4"><i class="fab fa-twitter"></i></a>
|
||||
<a href="#" class="text-muted fs-4"><i class="fab fa-discord"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-5 opacity-10">
|
||||
<div class="text-center text-muted small">
|
||||
© 2026 全球接码平台. 版权所有。 保护您的隐私,是我们不变的使命。
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Modals -->
|
||||
<div class="modal fade" id="registerModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content bg-white border-0 rounded-4 shadow-lg">
|
||||
<div class="modal-body p-5">
|
||||
<h3 class="fw-bold mb-4 text-center">新用户注册</h3>
|
||||
<form action="auth.php?action=register" method="POST">
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted">设置用户名</label>
|
||||
<input type="text" name="username" class="form-control" placeholder="仅支持字母和数字" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted">设置登录密码</label>
|
||||
<input type="password" name="password" class="form-control" placeholder="至少 6 位字符" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-muted">再次确认密码</label>
|
||||
<input type="password" name="confirm_password" class="form-control" placeholder="请与上述密码一致" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 py-3">立即注册</button>
|
||||
<button type="submit" class="btn btn-primary btn-main w-100 py-3 mt-2">
|
||||
注册并登入 / SIGN UP
|
||||
</button>
|
||||
<p class="text-center mt-4 mb-0 small text-muted fw-bold">
|
||||
已有账号?<a href="javascript:void(0)" class="text-primary text-decoration-none" data-bs-toggle="modal" data-bs-target="#loginModal">立即登入</a>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<div class="modal fade" id="loginModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content bg-white border-0 rounded-4 shadow-lg">
|
||||
<div class="modal-body p-5">
|
||||
<h3 class="fw-bold mb-4 text-center">登录账号</h3>
|
||||
<form action="auth.php?action=login" method="POST">
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted">用户名</label>
|
||||
<input type="text" name="username" class="form-control" required>
|
||||
<div class="modal-content border-0 rounded-5 p-4">
|
||||
<div class="modal-body p-4">
|
||||
<div class="text-center mb-4">
|
||||
<h3 class="fw-800">欢迎回来</h3>
|
||||
<p class="text-muted small">请输入您的凭据以访问控制面板</p>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-muted">密码</label>
|
||||
<input type="password" name="password" class="form-control" required>
|
||||
<form onsubmit="handleAuth(event, 'login')">
|
||||
<div class="input-group-custom">
|
||||
<label>用户名</label>
|
||||
<input type="text" name="username" class="form-control" placeholder="输入您的用户名" required>
|
||||
</div>
|
||||
<div class="input-group-custom">
|
||||
<label>密码</label>
|
||||
<input type="password" name="password" class="form-control" placeholder="输入登录密码" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-main w-100 py-3 mt-3">立即登录 / SIGN IN</button>
|
||||
<div class="text-center mt-4">
|
||||
<a href="javascript:void(0)" class="small text-muted fw-bold text-decoration-none" data-bs-toggle="modal" data-bs-target="#registerModal">没有账号?点击注册</a>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 py-3">立即登录</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@ -347,5 +254,33 @@ if (isset($_SESSION['user_id'])) {
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
async function handleAuth(e, type) {
|
||||
e.preventDefault();
|
||||
const form = e.target;
|
||||
const formData = new FormData(form);
|
||||
const btn = form.querySelector('button[type="submit"]');
|
||||
const originalText = btn.innerHTML;
|
||||
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-circle-notch fa-spin"></i> 处理中...';
|
||||
|
||||
try {
|
||||
const res = await fetch(`auth.php?action=${type}`, { method: 'POST', body: formData });
|
||||
const data = await res.json();
|
||||
if (data.code === 0) {
|
||||
window.location.href = 'dashboard.php';
|
||||
} else {
|
||||
alert(data.msg || '操作失败');
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = originalText;
|
||||
}
|
||||
} catch (error) {
|
||||
alert('网络异常');
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = originalText;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
150
orders.php
150
orders.php
@ -26,66 +26,87 @@ $orders = $stmt->fetchAll();
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #ff4d94;
|
||||
--secondary-color: #ff1a75;
|
||||
--bg-light: #fff8f9;
|
||||
--surface-light: #ffffff;
|
||||
--text-main: #2d1a1e;
|
||||
--text-muted: #8a6d71;
|
||||
--border-color: #ffd1dc;
|
||||
--primary: #3b82f6;
|
||||
--bg-body: #f1f5f9;
|
||||
--surface: #ffffff;
|
||||
--text-main: #1e293b;
|
||||
--text-muted: #64748b;
|
||||
--border-color: #e2e8f0;
|
||||
--sidebar-width: 280px;
|
||||
--radius-xl: 24px;
|
||||
}
|
||||
body {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
background-color: var(--bg-light);
|
||||
background-color: var(--bg-body);
|
||||
color: var(--text-main);
|
||||
overflow-x: hidden;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-left: var(--sidebar-width);
|
||||
padding: 2rem 3rem;
|
||||
padding: 2.5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.card-neo {
|
||||
.table-card {
|
||||
background: white;
|
||||
border: 2px solid var(--border-color);
|
||||
border-radius: 32px;
|
||||
padding: 24px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 8px 8px 0px var(--border-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 10px;
|
||||
}
|
||||
.table { vertical-align: middle; border-collapse: separate; border-spacing: 0 8px; }
|
||||
.table thead th {
|
||||
background: #f8fafc;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
font-weight: 700;
|
||||
font-size: 0.85rem;
|
||||
padding: 0 20px;
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
.table tbody tr {
|
||||
background-color: white;
|
||||
background: #fff;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.table tbody tr:hover { background: #f8fafc; }
|
||||
.table tbody td {
|
||||
border: none;
|
||||
padding: 16px 20px;
|
||||
vertical-align: middle;
|
||||
padding: 1.5rem;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
font-weight: 500;
|
||||
}
|
||||
.table tbody td:first-child { border-top-left-radius: 16px; border-bottom-left-radius: 16px; border: 1px solid var(--border-color); border-right: none; }
|
||||
.table tbody td:last-child { border-top-right-radius: 16px; border-bottom-right-radius: 16px; border: 1px solid var(--border-color); border-left: none; }
|
||||
.table tbody td:not(:first-child):not(:last-child) { border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); }
|
||||
.table tbody td:first-child { border-left: 1px solid #f1f5f9; border-top-left-radius: 12px; border-bottom-left-radius: 12px; }
|
||||
.table tbody td:last-child { border-right: 1px solid #f1f5f9; border-top-right-radius: 12px; border-bottom-right-radius: 12px; }
|
||||
|
||||
.badge-custom { padding: 8px 16px; border-radius: 12px; font-weight: 600; font-size: 0.8rem; }
|
||||
.bg-received { background-color: rgba(69, 179, 107, 0.1); color: #28a745; }
|
||||
.bg-canceled { background-color: rgba(220, 53, 69, 0.1); color: #dc3545; }
|
||||
.bg-pending { background-color: rgba(255, 77, 148, 0.1); color: var(--primary-color); }
|
||||
.status-pill {
|
||||
padding: 6px 14px;
|
||||
border-radius: 100px;
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.status-received { background: #dcfce7; color: #166534; }
|
||||
.status-canceled { background: #fee2e2; color: #991b1b; }
|
||||
.status-pending { background: #eff6ff; color: #1e40af; }
|
||||
|
||||
.sms-box {
|
||||
background: #f1f5f9;
|
||||
color: #334155;
|
||||
padding: 8px 16px;
|
||||
border-radius: 10px;
|
||||
font-family: 'JetBrains Mono', 'Courier New', monospace;
|
||||
font-weight: 700;
|
||||
border: 1px solid #e2e8f0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.main-content { margin-left: 80px; padding: 1.5rem; }
|
||||
.main-content { margin-left: 0; padding: 1.5rem; }
|
||||
.sidebar { display: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -95,51 +116,60 @@ $orders = $stmt->fetchAll();
|
||||
|
||||
<div class="main-content">
|
||||
<div class="mb-5">
|
||||
<h2 class="fw-bold mb-1">接码记录清单</h2>
|
||||
<p class="text-muted">您可以查看所有历史获取过的号码及短信内容</p>
|
||||
<h1 class="fw-bold mb-1" style="font-size: 1.5rem;">接码记录 <span class="text-muted fw-medium ms-2 fs-6">ORDER HISTORY</span></h1>
|
||||
<p class="text-muted small fw-medium mb-0">记录您账户下所有的号码获取详情与收码状态清单</p>
|
||||
</div>
|
||||
|
||||
<div class="card-neo">
|
||||
<div class="table-card">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>任务时间</th>
|
||||
<th>项目名称</th>
|
||||
<th>临时号码</th>
|
||||
<th>短信内容</th>
|
||||
<th>执行状态</th>
|
||||
<th>任务时间 / TIME</th>
|
||||
<th>项目/国家 / DETAILS</th>
|
||||
<th>号码 / NUMBER</th>
|
||||
<th>短信内容 / SMS</th>
|
||||
<th class="text-center">状态 / STATUS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($orders as $order): ?>
|
||||
<tr>
|
||||
<td class="small text-muted"><?= date('m-d H:i', strtotime($order['created_at'])) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($order['service_name'] ?: '未知项目') ?></td>
|
||||
<td class="fw-bold text-primary"><?= $order['number'] ?></td>
|
||||
<td>
|
||||
<?php if ($order['sms_content']): ?>
|
||||
<span class="p-2 rounded px-3 fw-bold" style="background-color: var(--bg-light); color: var(--primary-color); border: 1px solid var(--border-color);"><?= htmlspecialchars($order['sms_content']) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted opacity-50">-</span>
|
||||
<?php endif; ?>
|
||||
<td class="small text-muted fw-bold">
|
||||
<div><?= date('Y-m-d', strtotime($order['created_at'])) ?></div>
|
||||
<div class="opacity-50"><?= date('H:i:s', strtotime($order['created_at'])) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($order['status'] === 'received'): ?>
|
||||
<span class="badge-custom bg-received">成功收码</span>
|
||||
<?php elseif ($order['status'] === 'canceled'): ?>
|
||||
<span class="badge-custom bg-canceled">已释放</span>
|
||||
<div class="fw-bold"><?= htmlspecialchars($order['service_name']) ?></div>
|
||||
<div class="small text-muted fw-medium"><?= htmlspecialchars($order['country_name']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-bold text-primary fs-5" style="letter-spacing: 0.5px;"><?= $order['number'] ?></div>
|
||||
<div class="small text-muted opacity-50">REQ_ID: <?= $order['request_id'] ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($order['sms_content']): ?>
|
||||
<span class="sms-box"><?= htmlspecialchars($order['sms_content']) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge-custom bg-pending">等待中</span>
|
||||
<span class="text-muted opacity-25">PENDING..</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<?php if ($order['status'] === 'received'): ?>
|
||||
<span class="status-pill status-received">SUCCESS</span>
|
||||
<?php elseif ($order['status'] === 'canceled' || $order['status'] === 'expired'): ?>
|
||||
<span class="status-pill status-canceled">CLOSED</span>
|
||||
<?php else: ?>
|
||||
<span class="status-pill status-pending">WAITING</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($orders)): ?>
|
||||
<tr>
|
||||
<td colspan="5" class="text-center py-5 text-muted">
|
||||
<i class="fas fa-history fa-3x mb-3 opacity-25"></i>
|
||||
<p>暂无任何接码记录</p>
|
||||
<td colspan="5" class="text-center py-5">
|
||||
<div class="opacity-10 mb-3"><i class="fas fa-history fa-4x"></i></div>
|
||||
<div class="fw-bold text-muted">暂无任何历史接码记录 / NO ORDERS</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
574
recharge.php
574
recharge.php
@ -11,204 +11,173 @@ $stmt = $pdo->prepare("SELECT username, balance FROM users WHERE id = ?");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT setting_value FROM settings WHERE setting_key = 'usdt_trc20_address'");
|
||||
$stmt->execute();
|
||||
$trc20_address = $stmt->fetchColumn() ?: 'TEm1B...TRC20_ADDRESS_HERE';
|
||||
|
||||
$stmt = $pdo->prepare("SELECT setting_value FROM settings WHERE setting_key = 'usdt_erc20_address'");
|
||||
$stmt->execute();
|
||||
$erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
$settings = $pdo->query("SELECT setting_key, setting_value FROM settings")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
$trc20_address = $settings['usdt_trc20_address'] ?? 'TEm1B...TRC20_ADDRESS_HERE';
|
||||
$erc20_address = $settings['usdt_erc20_address'] ?? '0x71C...ERC20_ADDRESS_HERE';
|
||||
$site_name = $settings['site_name'] ?? '全球接码';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>充值中心 - 全球接码 (Recharge)</title>
|
||||
<title>充值中心 - <?= htmlspecialchars($site_name) ?></title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/qrcode-generator@1.4.4/qrcode.min.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #ff4d94;
|
||||
--secondary-color: #ff1a75;
|
||||
--bg-light: #fff8f9;
|
||||
--surface-light: #ffffff;
|
||||
--text-main: #2d1a1e;
|
||||
--text-muted: #8a6d71;
|
||||
--border-color: #ffd1dc;
|
||||
--primary: #3b82f6;
|
||||
--primary-gradient: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
||||
--bg-body: #f1f5f9;
|
||||
--surface: #ffffff;
|
||||
--text-main: #1e293b;
|
||||
--text-muted: #64748b;
|
||||
--border-color: #e2e8f0;
|
||||
--sidebar-width: 280px;
|
||||
--radius-xl: 24px;
|
||||
--radius-lg: 16px;
|
||||
}
|
||||
body {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
background-color: var(--bg-light);
|
||||
background-color: var(--bg-body);
|
||||
color: var(--text-main);
|
||||
overflow-x: hidden;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-left: var(--sidebar-width);
|
||||
padding: 2rem 3rem;
|
||||
padding: 2.5rem;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.card-neo {
|
||||
.card-custom {
|
||||
background: white;
|
||||
border: 2px solid var(--border-color);
|
||||
border-radius: 32px;
|
||||
padding: 40px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 8px 8px 0px var(--border-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: 2.5rem;
|
||||
margin-bottom: 2rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.network-btn {
|
||||
background-color: #fff;
|
||||
border: 2px solid var(--border-color);
|
||||
background-color: #f8fafc;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
color: var(--text-muted);
|
||||
padding: 15px;
|
||||
border-radius: 16px;
|
||||
padding: 18px;
|
||||
border-radius: var(--radius-lg);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
transition: all 0.2s ease;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
flex: 1;
|
||||
}
|
||||
.network-btn.active {
|
||||
border-color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
background-color: rgba(255, 77, 148, 0.05);
|
||||
box-shadow: 0 4px 12px rgba(255, 77, 148, 0.1);
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
background-color: #eff6ff;
|
||||
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
.qr-container {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 24px;
|
||||
display: inline-block;
|
||||
margin: 20px 0;
|
||||
border: 2px solid var(--border-color);
|
||||
box-shadow: 0 10px 30px rgba(255, 77, 148, 0.1);
|
||||
}
|
||||
|
||||
.address-container {
|
||||
position: relative;
|
||||
background-color: var(--bg-light);
|
||||
.qr-card {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
border-radius: 20px;
|
||||
border: 2px dashed var(--border-color);
|
||||
transition: all 0.3s ease;
|
||||
border-radius: var(--radius-xl);
|
||||
display: inline-block;
|
||||
border: 1px solid #f1f5f9;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.address-box {
|
||||
word-break: break-all;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 1.2rem;
|
||||
color: var(--primary-color);
|
||||
font-weight: 800;
|
||||
margin-right: 60px;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 14px;
|
||||
.address-box-wrapper {
|
||||
background-color: #f8fafc;
|
||||
padding: 20px 24px;
|
||||
border-radius: var(--radius-lg);
|
||||
border: 2px dashed #cbd5e1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
justify-content: space-between;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
word-break: break-all;
|
||||
font-family: 'JetBrains Mono', 'Courier New', monospace;
|
||||
font-size: 1.1rem;
|
||||
color: #1e293b;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn-copy {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 48px; height: 48px;
|
||||
border-radius: 14px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
cursor: pointer; transition: all 0.2s;
|
||||
}
|
||||
.btn-copy:hover { transform: scale(1.05); background: #2563eb; }
|
||||
|
||||
.btn-primary-action {
|
||||
background: var(--primary-gradient);
|
||||
border: none;
|
||||
padding: 20px;
|
||||
border-radius: var(--radius-lg);
|
||||
font-weight: 800;
|
||||
color: white;
|
||||
width: 100%;
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 8px 25px rgba(37, 99, 235, 0.25);
|
||||
}
|
||||
.btn-primary-action:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(37, 99, 235, 0.35); }
|
||||
|
||||
.step-panel { display: none; }
|
||||
.step-panel.active { display: block; animation: fadeInUp 0.4s ease-out; }
|
||||
@keyframes fadeInUp { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: translateY(0); } }
|
||||
|
||||
.scanner-circle {
|
||||
width: 100px; height: 100px;
|
||||
border: 3px solid var(--primary);
|
||||
border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
}
|
||||
.scanner-circle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -10px; left: -10px; right: -10px; bottom: -10px;
|
||||
border: 2px solid rgba(59, 130, 246, 0.2);
|
||||
border-radius: 50%;
|
||||
animation: ping 1.5s infinite;
|
||||
}
|
||||
@keyframes ping { 75%, 100% { transform: scale(1.4); opacity: 0; } }
|
||||
|
||||
.status-badge {
|
||||
padding: 8px 16px;
|
||||
border-radius: 100px;
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.status-sync { background: #dcfce7; color: #166534; }
|
||||
|
||||
.amt-btn {
|
||||
background: #fff;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
padding: 15px;
|
||||
border-radius: var(--radius-lg);
|
||||
font-weight: 800;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.copy-btn:hover { background: var(--secondary-color); transform: translateY(-50%) scale(1.05); }
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
border: none;
|
||||
padding: 18px 30px;
|
||||
border-radius: 20px;
|
||||
font-weight: 800;
|
||||
color: white;
|
||||
box-shadow: 0 8px 25px rgba(255, 77, 148, 0.3);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.btn-primary:hover { transform: translateY(-3px); box-shadow: 0 12px 30px rgba(255, 77, 148, 0.4); }
|
||||
|
||||
.step-container { display: none; }
|
||||
.step-container.active { display: block; animation: slideUp 0.6s cubic-bezier(0.16, 1, 0.3, 1); }
|
||||
@keyframes slideUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
|
||||
|
||||
.status-overlay {
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
backdrop-filter: blur(15px);
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.6s ease;
|
||||
}
|
||||
.status-overlay.show { visibility: visible; opacity: 1; }
|
||||
|
||||
.instruction-item {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.instruction-item:last-child { margin-bottom: 0; }
|
||||
.instruction-icon {
|
||||
width: 32px; height: 32px;
|
||||
background: var(--bg-light);
|
||||
color: var(--primary-color);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
font-weight: 800;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.pulse-scanner {
|
||||
width: 100px; height: 100px;
|
||||
border: 4px solid var(--primary-color);
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
animation: pulse 2s infinite;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 77, 148, 0.7); }
|
||||
70% { transform: scale(1); box-shadow: 0 0 0 20px rgba(255, 77, 148, 0); }
|
||||
100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 77, 148, 0); }
|
||||
}
|
||||
|
||||
.notice-box {
|
||||
background: #fff5f8;
|
||||
border-left: 4px solid var(--primary-color);
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.accordion-button:not(.collapsed) {
|
||||
background-color: rgba(255, 77, 148, 0.05);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.amt-btn:hover { border-color: var(--primary); color: var(--primary); background: #f8fafc; }
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.main-content { margin-left: 80px; padding: 1.5rem; }
|
||||
.main-content { margin-left: 0; padding: 1.5rem; }
|
||||
.sidebar { display: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -217,125 +186,119 @@ $erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
<?php include 'includes/sidebar.php'; ?>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="mb-5 d-flex justify-content-between align-items-end">
|
||||
<div class="d-flex justify-content-between align-items-center mb-5">
|
||||
<div>
|
||||
<h2 class="fw-bold mb-1"><i class="fas fa-wallet me-2 text-primary"></i> 资产充值 (Asset Recharge)</h2>
|
||||
<p class="text-muted mb-0">USDT 全自动到账,由区块链共识网络提供安全保障</p>
|
||||
<h1 class="fw-bold mb-1" style="font-size: 1.5rem;">资产充值 <span class="text-muted fw-medium ms-2 fs-6">RECHARGE CENTER</span></h1>
|
||||
<p class="text-muted small mb-0 fw-medium">USDT 全自动区块监听,即时入账安全有保障</p>
|
||||
</div>
|
||||
<div class="text-end bg-white border p-3 px-4 rounded-4 shadow-sm d-flex align-items-center gap-3">
|
||||
<div class="text-end">
|
||||
<span class="small text-muted fw-bold d-block">当前可用余额</span>
|
||||
<span class="h4 fw-bold text-primary mb-0">$<?= number_format($user['balance'], 2) ?></span>
|
||||
<div class="small text-muted fw-bold" style="font-size: 10px; letter-spacing: 0.5px;">BALANCE</div>
|
||||
<div class="h4 fw-bold text-primary mb-0">$<?= number_format($user['balance'] ?? 0, 2) ?></div>
|
||||
</div>
|
||||
<div class="bg-primary bg-opacity-10 text-primary rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
|
||||
<i class="fas fa-wallet"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-xl-8">
|
||||
<div class="card-neo">
|
||||
<!-- Step 1: Input Amount -->
|
||||
<div id="step1" class="step-container active">
|
||||
<h4 class="fw-bold mb-4">1. 设定充值金额 (Set Amount)</h4>
|
||||
<div class="notice-box">
|
||||
<p class="small mb-0">
|
||||
<i class="fas fa-info-circle me-1"></i> 为了识别您的充值订单,系统会自动为您的金额添加<strong>唯一的随机小数</strong>。请在支付时务必支付<strong>包含小数点的精确金额</strong>。
|
||||
<div class="card-custom">
|
||||
<!-- Step 1 -->
|
||||
<div id="step1" class="step-panel active">
|
||||
<h5 class="fw-bold mb-4" style="color: #334155;">1. 输入充值数额 / AMOUNT</h5>
|
||||
<div class="p-4 bg-primary bg-opacity-10 rounded-4 mb-4" style="border-left: 4px solid var(--primary);">
|
||||
<p class="small text-primary fw-bold mb-0">
|
||||
<i class="fas fa-info-circle me-1"></i> 为了极速识别您的支付,系统会生成一个唯一的<strong>随机小数</strong>。请务必支付<strong>包含小数点的准确金额</strong>。
|
||||
</p>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label fw-bold text-muted small">充值金额 (USDT)</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-white border-end-0 border-2" style="border-color: var(--border-color); color: var(--primary-color); font-weight: 800; padding: 0 25px;">$</span>
|
||||
<input type="number" id="inputAmount" class="form-control border-start-0 border-2" style="border-color: var(--border-color); font-size: 1.8rem; font-weight: 800;" placeholder="10.00" min="10" step="1">
|
||||
|
||||
<div class="mb-5 text-center py-4">
|
||||
<label class="form-label fw-bold text-muted small mb-3">充值金额 (USDT)</label>
|
||||
<div class="d-flex align-items-center justify-content-center gap-2">
|
||||
<span class="fs-1 fw-bold text-muted opacity-25">$</span>
|
||||
<input type="number" id="inputAmount" class="form-control border-0 text-center fw-bold" style="font-size: 4rem; width: 300px; color: var(--primary);" placeholder="0" min="10" step="1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-5">
|
||||
<?php foreach([10, 50, 100, 200, 500, 1000] as $amt): ?>
|
||||
<div class="col-4 col-md-2">
|
||||
<button class="btn btn-outline-pink w-100 py-3 border-2 rounded-4" style="border-color: var(--border-color); color: var(--primary-color); font-weight: 800;" onclick="setAmount(<?= $amt ?>)"><?= $amt ?></button>
|
||||
<button class="btn amt-btn w-100" onclick="setAmount(<?= $amt ?>)"><?= $amt ?></button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary w-100 py-4" onclick="confirmOrder()">
|
||||
<i class="fas fa-arrow-right me-2"></i> 生成专属支付订单
|
||||
<button class="btn-primary-action py-4 mt-4" onclick="confirmOrder()">
|
||||
生成支付订单 / CONFIRM ORDER <i class="fas fa-chevron-right ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Payment Details -->
|
||||
<div id="step2" class="step-container">
|
||||
<div class="d-flex justify-content-between align-items-center mb-5">
|
||||
<!-- Step 2 -->
|
||||
<div id="step2" class="step-panel">
|
||||
<div class="d-flex justify-content-between align-items-center mb-5 pb-4 border-bottom">
|
||||
<div>
|
||||
<h4 class="fw-bold mb-1">2. 完成链上支付</h4>
|
||||
<p class="text-muted small mb-0" id="orderIdDisplay">正在创建订单...</p>
|
||||
<h5 class="fw-bold mb-1">2. 完成区块链支付 / PAYMENT</h5>
|
||||
<div class="status-badge status-sync" id="orderIdDisplay">正在连接节点...</div>
|
||||
</div>
|
||||
<div class="text-end bg-light p-3 rounded-4 border">
|
||||
<div class="text-end">
|
||||
<div class="h2 fw-bold text-primary mb-0" id="displayAmount">0.00</div>
|
||||
<div class="small text-muted fw-bold">待支付精确金额 (USDT)</div>
|
||||
<div class="small text-muted fw-bold" style="font-size: 10px;">PRECISE AMOUNT (USDT)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="row g-4 mb-5">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-bold text-muted mb-3">A. 选择支付网络</label>
|
||||
<div class="row g-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label fw-bold text-muted mb-3 small">A. 选择支付网络 / NETWORK</label>
|
||||
<div class="d-flex gap-3 mb-4">
|
||||
<div class="network-btn active" id="btnTRC" onclick="selectNetwork('TRC20')">
|
||||
<div class="fw-bold">TRC20</div>
|
||||
<div class="small opacity-50" style="font-size: 0.6rem;">波场/TRON</div>
|
||||
<div class="fs-5">TRC20</div>
|
||||
<div class="small opacity-50">波场 TRON</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="network-btn" id="btnERC" onclick="selectNetwork('ERC20')">
|
||||
<div class="fw-bold">ERC20</div>
|
||||
<div class="small opacity-50" style="font-size: 0.6rem;">以太坊/ETH</div>
|
||||
</div>
|
||||
<div class="fs-5">ERC20</div>
|
||||
<div class="small opacity-50">以太坊 ETH</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 p-4 rounded-4" style="background: #fff9f0; border: 1px solid #ffeeba;">
|
||||
<p class="small mb-0 text-dark">
|
||||
<i class="fas fa-exclamation-triangle text-warning me-2"></i>
|
||||
<strong>必看操作指南:</strong> <br>
|
||||
1. 充值网络必须与您钱包发送的网络一致,否则资产将丢失。<br>
|
||||
2. 支付金额必须<strong>精确到小数点后两位</strong>,这是识别您身份的唯一凭据。<br>
|
||||
3. 支付完成后,请<strong>停留在本页面</strong>。系统检测到款项后会自动为您跳转。
|
||||
</p>
|
||||
<div class="alert alert-warning border-0 rounded-4 p-4" style="background: #fffbeb;">
|
||||
<h6 class="fw-bold mb-2 small" style="color: #92400e;"><i class="fas fa-exclamation-triangle me-2"></i> 核心支付准则</h6>
|
||||
<ol class="small mb-0 ps-3" style="color: #92400e;">
|
||||
<li class="mb-1">转账金额必须<strong>精确到小数点后两位</strong>。</li>
|
||||
<li class="mb-1">转账网络必须选择与您选择的选项一致。</li>
|
||||
<li>支付后请不要关闭此页面,等待系统自动跳转。</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 text-center">
|
||||
<div class="qr-container" id="qrcode"></div>
|
||||
<div class="mt-2">
|
||||
<span class="badge bg-light text-primary p-2 px-4 rounded-pill fw-bold border">
|
||||
<i class="fas fa-hourglass-half me-2"></i> 订单监听剩余时间: <span id="countdown">60:00</span>
|
||||
</span>
|
||||
<div class="qr-card" id="qrcode"></div>
|
||||
<div class="mt-4">
|
||||
<div class="badge bg-light text-primary border p-2 px-4 rounded-pill fw-bold">
|
||||
<i class="fas fa-clock-rotate-left me-2"></i> 有效期: <span id="countdown">60:00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-5">
|
||||
<label class="text-muted small mb-2 d-block fw-bold">B. 复制专属收款地址</label>
|
||||
<div class="address-container">
|
||||
<div class="address-box" id="addressBox">正在获取地址...</div>
|
||||
<button class="copy-btn" onclick="copyAddress()" title="点击复制"><i class="fas fa-copy"></i></button>
|
||||
<label class="text-muted small mb-2 d-block fw-bold px-1">B. 复制收款地址 / ADDRESS</label>
|
||||
<div class="address-box-wrapper">
|
||||
<div class="address-text" id="addressBox">正在加载...</div>
|
||||
<button class="btn-copy" onclick="copyAddress()" title="点击复制"><i class="fas fa-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column align-items-center py-5 border-top">
|
||||
<div class="pulse-scanner">
|
||||
<i class="fas fa-broadcast-tower text-primary h3 mb-0"></i>
|
||||
<div class="d-flex flex-column align-items-center py-4">
|
||||
<div class="scanner-circle">
|
||||
<i class="fas fa-satellite-dish text-primary fs-3"></i>
|
||||
</div>
|
||||
<h5 class="fw-bold mb-2">正在实时监控收款地址...</h5>
|
||||
<p class="text-muted small mb-4 text-center">
|
||||
我们正在 24/7 监听区块链节点数据。一旦检测到与您金额匹配的款项,将立即跳转。<br>
|
||||
<span class="text-primary fw-bold" id="pollingStatus">正在连接区块链节点...</span>
|
||||
</p>
|
||||
<h6 class="fw-bold mb-2">正在监听区块确认...</h6>
|
||||
<p class="text-muted small text-center mb-5 px-5">我们正在 24/7 监听您的专属付款。一旦链上确认数达标,系统将瞬间为您入账。</p>
|
||||
|
||||
<div class="d-flex gap-3 w-100">
|
||||
<button class="btn btn-light flex-grow-1 py-3 rounded-4 fw-bold border" onclick="goBackToStep1()">
|
||||
<i class="fas fa-edit me-1"></i> 修改金额
|
||||
</button>
|
||||
<button class="btn btn-primary flex-grow-1 py-3 rounded-4" onclick="checkStatusManual()">
|
||||
<i class="fas fa-sync-alt me-1"></i> 手动刷新到账状态
|
||||
</button>
|
||||
<button class="btn btn-light border flex-grow-1 py-3 rounded-4 fw-bold" style="color: #64748b;" onclick="goBackToStep1()">修改金额</button>
|
||||
<button class="btn btn-primary flex-grow-1 py-3 rounded-4 fw-bold shadow-sm" onclick="checkStatusManual()">手动刷新状态</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -343,93 +306,37 @@ $erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
</div>
|
||||
|
||||
<div class="col-xl-4">
|
||||
<div class="card-neo">
|
||||
<h5 class="fw-bold mb-4"><i class="fas fa-question-circle me-2 text-primary"></i> 常见问题 (FAQ)</h5>
|
||||
|
||||
<div class="accordion accordion-flush" id="faqAccordion">
|
||||
<div class="accordion-item border-0 mb-3 bg-light rounded-4 overflow-hidden">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed bg-transparent fw-bold small py-3" type="button" data-bs-toggle="collapse" data-bs-target="#faq1">
|
||||
为什么要支付包含随机小数的金额?
|
||||
</button>
|
||||
</h2>
|
||||
<div id="faq1" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
|
||||
<div class="accordion-body small pt-0 opacity-75">
|
||||
为了实现无人值守的自动化到账,系统需要区分不同用户的充值。通过为每个订单分配独特的随机小数(如 100.42),我们可以在收款地址检测到对应的精确数值时,瞬间识别出是您的充值并自动入账,无需您手动上传截图。
|
||||
<div class="card-custom" style="padding: 2rem;">
|
||||
<h6 class="fw-bold mb-4" style="color: #334155;"><i class="fas fa-lightbulb text-warning me-2"></i> 充值助手 / HELP</h6>
|
||||
<div class="mb-4">
|
||||
<div class="fw-bold mb-1 small">为什么要支付精确小数?</div>
|
||||
<p class="small text-muted mb-0">金额是唯一的。精准支付后,系统可实现秒级自动识别入账。否则需要联系人工核实。</p>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="fw-bold mb-1 small">多久到账?</div>
|
||||
<p class="small text-muted mb-0">TRC20 网络通常在 1 分钟内。ERC20 视网络拥堵情况,通常在 5-10 分钟。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item border-0 mb-3 bg-light rounded-4 overflow-hidden">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed bg-transparent fw-bold small py-3" type="button" data-bs-toggle="collapse" data-bs-target="#faq2">
|
||||
支付后多久可以到账?
|
||||
</button>
|
||||
</h2>
|
||||
<div id="faq2" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
|
||||
<div class="accordion-body small pt-0 opacity-75">
|
||||
到账时间取决于区块链网络的确认速度。TRC20 网络通常在 1-2 分钟内完成确认,ERC20 网络视网络拥堵情况可能需要 5-10 分钟。一旦网络确认达到 1 个确认数,系统将立即为您增加余额。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item border-0 mb-3 bg-light rounded-4 overflow-hidden">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed bg-transparent fw-bold small py-3" type="button" data-bs-toggle="collapse" data-bs-target="#faq3">
|
||||
如果金额支付错误(未支付小数)怎么办?
|
||||
</button>
|
||||
</h2>
|
||||
<div id="faq3" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
|
||||
<div class="accordion-body small pt-0 opacity-75">
|
||||
如果您支付的金额不包含指定的小数,系统将无法自动识别您的订单。这种情况下,请务必保留您的转账截图和 TXID,并联系在线客服进行人工手动审核和上分。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item border-0 mb-3 bg-light rounded-4 overflow-hidden">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed bg-transparent fw-bold small py-3" type="button" data-bs-toggle="collapse" data-bs-target="#faq4">
|
||||
支持哪些代币充值?
|
||||
</button>
|
||||
</h2>
|
||||
<div id="faq4" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
|
||||
<div class="accordion-body small pt-0 opacity-75">
|
||||
目前系统仅支持 USDT (Tether) 充值。请确保您在转账时选择了正确的币种。请勿向收款地址发送非 USDT 资产,否则资产将永久丢失。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 p-4 bg-primary text-white rounded-4 shadow-sm">
|
||||
<h6 class="fw-bold mb-2"><i class="fas fa-headset me-2"></i> 充值遇到问题?</h6>
|
||||
<p class="small mb-3 opacity-75">我们提供 24/7 全天候技术支持。如果您的充值超过 30 分钟未到账,请通过工单联系我们。</p>
|
||||
<a href="support.php" class="btn btn-white btn-sm w-100 fw-bold">联系在线客服</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-neo mt-4 border-primary">
|
||||
<h6 class="fw-bold mb-3">区块链监控节点状态</h6>
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="spinner-grow spinner-grow-sm text-success me-2" style="animation-duration: 3s;"></div>
|
||||
<span class="small text-muted">TRON (TRC20) 节点: <span class="text-success fw-bold">Active</span></span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="spinner-grow spinner-grow-sm text-success me-2" style="animation-duration: 2.5s;"></div>
|
||||
<span class="small text-muted">Ethereum (ERC20) 节点: <span class="text-success fw-bold">Active</span></span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="spinner-grow spinner-grow-sm text-success me-2" style="animation-duration: 4s;"></div>
|
||||
<span class="small text-muted">API 网关同步: <span class="text-success fw-bold">Synced</span></span>
|
||||
<div class="mt-5 p-4 bg-primary rounded-4 text-white shadow-lg" style="background: var(--primary-gradient) !important;">
|
||||
<h6 class="fw-bold mb-2">需要人工支持?</h6>
|
||||
<p class="small opacity-75 mb-3">如果金额支付错误或长时间未到账,请立即联系在线客服。</p>
|
||||
<a href="support.php" class="btn btn-white btn-sm w-100 fw-bold py-2 rounded-3" style="background: white; color: var(--primary);">发起咨询 / SUPPORT</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-overlay" id="successOverlay">
|
||||
<div class="mb-4"><i class="fas fa-check-circle text-success" style="font-size: 8rem;"></i></div>
|
||||
<h1 class="fw-bold mb-2">支付已确认!</h1>
|
||||
<p class="text-muted h5">系统已识别您的充值并自动入账,正在跳转工作台...</p>
|
||||
<div class="modal fade" id="successModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 rounded-5 overflow-hidden text-center p-5">
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-check-circle text-success" style="font-size: 5rem;"></i>
|
||||
</div>
|
||||
<h3 class="fw-bold">充值确认成功!</h3>
|
||||
<p class="text-muted mb-4">您的余额已成功更新。欢迎回到工作台继续接码。</p>
|
||||
<button class="btn btn-primary btn-lg w-100 py-3 rounded-4 fw-bold" onclick="window.location.href='dashboard.php'">立即前往工作台</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@ -442,12 +349,12 @@ $erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
|
||||
async function confirmOrder() {
|
||||
const amt = document.getElementById('inputAmount').value;
|
||||
if (amt < 10) { alert('最低充值金额为 10 USDT'); return; }
|
||||
if (!amt || amt < 10) { alert('最低充值金额为 10 USDT'); return; }
|
||||
|
||||
const btn = event.currentTarget;
|
||||
const oldHtml = btn.innerHTML;
|
||||
const originalText = btn.innerHTML;
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>正在连接区块链支付网关...';
|
||||
btn.innerHTML = '<i class="fas fa-circle-notch fa-spin me-2"></i>正在连接区块链网关...';
|
||||
|
||||
try {
|
||||
const formData = new FormData();
|
||||
@ -456,38 +363,25 @@ $erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
const data = await res.json();
|
||||
if (data.code === 0) {
|
||||
currentRechargeId = data.recharge_id;
|
||||
document.getElementById('orderIdDisplay').textContent = '支付流水号: #RE' + currentRechargeId;
|
||||
document.getElementById('orderIdDisplay').textContent = 'ORDER ID: #RE' + currentRechargeId;
|
||||
document.getElementById('displayAmount').textContent = parseFloat(data.amount).toFixed(2);
|
||||
document.getElementById('step1').classList.remove('active');
|
||||
document.getElementById('step2').classList.add('active');
|
||||
updateDisplay();
|
||||
startTimer();
|
||||
startPollingStatus();
|
||||
} else {
|
||||
alert(data.msg);
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = oldHtml;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = oldHtml;
|
||||
}
|
||||
} else { alert(data.msg); btn.disabled = false; btn.innerHTML = originalText; }
|
||||
} catch (e) { btn.disabled = false; btn.innerHTML = originalText; }
|
||||
}
|
||||
|
||||
function startPollingStatus() {
|
||||
const statusEl = document.getElementById('pollingStatus');
|
||||
let dots = '';
|
||||
pollInterval = setInterval(async () => {
|
||||
dots = dots.length >= 3 ? '' : dots + '.';
|
||||
statusEl.textContent = '实时同步区块数据中' + dots;
|
||||
|
||||
try {
|
||||
const res = await fetch(`ajax_handler.php?action=check_recharge_status&recharge_id=${currentRechargeId}`);
|
||||
const data = await res.json();
|
||||
if (data.code === 0 && data.status === 'completed') {
|
||||
clearInterval(pollInterval);
|
||||
document.getElementById('successOverlay').classList.add('show');
|
||||
new bootstrap.Modal(document.getElementById('successModal')).show();
|
||||
setTimeout(() => window.location.href = 'dashboard.php', 3000);
|
||||
}
|
||||
} catch (e) {}
|
||||
@ -496,26 +390,15 @@ $erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
|
||||
async function checkStatusManual() {
|
||||
const btn = event.currentTarget;
|
||||
const oldHtml = btn.innerHTML;
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>正在查询链上记录...';
|
||||
|
||||
const old = btn.innerHTML;
|
||||
btn.disabled = true; btn.innerHTML = '<i class="fas fa-circle-notch fa-spin"></i>';
|
||||
try {
|
||||
const res = await fetch(`ajax_handler.php?action=check_recharge_status&recharge_id=${currentRechargeId}`);
|
||||
const data = await res.json();
|
||||
if (data.code === 0 && data.status === 'completed') {
|
||||
document.getElementById('successOverlay').classList.add('show');
|
||||
setTimeout(() => window.location.href = 'dashboard.php', 3000);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = oldHtml;
|
||||
}, 1000);
|
||||
}
|
||||
} catch (e) {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = oldHtml;
|
||||
}
|
||||
new bootstrap.Modal(document.getElementById('successModal')).show();
|
||||
} else { setTimeout(() => { btn.disabled = false; btn.innerHTML = old; }, 1000); }
|
||||
} catch (e) { btn.disabled = false; btn.innerHTML = old; }
|
||||
}
|
||||
|
||||
function selectNetwork(net) {
|
||||
@ -529,18 +412,17 @@ $erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
const addr = addresses[currentNetwork];
|
||||
document.getElementById('addressBox').textContent = addr;
|
||||
const qr = qrcode(0, 'M');
|
||||
qr.addData(addr);
|
||||
qr.make();
|
||||
qr.addData(addr); qr.make();
|
||||
document.getElementById('qrcode').innerHTML = qr.createImgTag(6, 0);
|
||||
}
|
||||
|
||||
function copyAddress() {
|
||||
const addr = document.getElementById('addressBox').textContent;
|
||||
navigator.clipboard.writeText(addr).then(() => {
|
||||
const btn = document.querySelector('.copy-btn');
|
||||
const oldHtml = btn.innerHTML;
|
||||
const btn = document.querySelector('.btn-copy');
|
||||
const old = btn.innerHTML;
|
||||
btn.innerHTML = '<i class="fas fa-check"></i>';
|
||||
setTimeout(() => btn.innerHTML = oldHtml, 2000);
|
||||
setTimeout(() => btn.innerHTML = old, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
@ -554,12 +436,12 @@ $erc20_address = $stmt->fetchColumn() ?: '0x71C...ERC20_ADDRESS_HERE';
|
||||
}
|
||||
|
||||
function goBackToStep1() {
|
||||
if (!confirm('离开此页面将关闭当前订单监听。确定返回修改金额吗?')) return;
|
||||
if (!confirm('确定返回修改金额?当前订单将作废。')) return;
|
||||
document.getElementById('step2').classList.remove('active');
|
||||
document.getElementById('step1').classList.add('active');
|
||||
clearInterval(timerInterval); clearInterval(pollInterval);
|
||||
const btn = document.querySelector('#step1 button.btn-primary');
|
||||
btn.disabled = false;
|
||||
document.querySelector('#step1 button.btn-primary-action').disabled = false;
|
||||
document.querySelector('#step1 button.btn-primary-action').innerHTML = '生成支付订单 / CONFIRM ORDER <i class="fas fa-chevron-right ms-2"></i>';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
100
support.php
100
support.php
@ -34,67 +34,86 @@ $messages = $stmt->fetchAll();
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #ff4d94;
|
||||
--secondary-color: #ff1a75;
|
||||
--bg-light: #fff8f9;
|
||||
--surface-light: #ffffff;
|
||||
--text-main: #2d1a1e;
|
||||
--text-muted: #8a6d71;
|
||||
--border-color: #ffd1dc;
|
||||
--primary: #3b82f6;
|
||||
--primary-gradient: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
||||
--bg-body: #f1f5f9;
|
||||
--surface: #ffffff;
|
||||
--text-main: #1e293b;
|
||||
--text-muted: #64748b;
|
||||
--border-color: #e2e8f0;
|
||||
--sidebar-width: 280px;
|
||||
--radius-xl: 24px;
|
||||
}
|
||||
body {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
background-color: var(--bg-light);
|
||||
background-color: var(--bg-body);
|
||||
color: var(--text-main);
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-left: var(--sidebar-width);
|
||||
padding: 2rem 3rem;
|
||||
padding: 2.5rem;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.chat-card {
|
||||
.chat-container {
|
||||
background: white;
|
||||
border: 2px solid var(--border-color);
|
||||
border-radius: 32px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-xl);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
box-shadow: 8px 8px 0px var(--border-color);
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.chat-body {
|
||||
flex: 1;
|
||||
padding: 30px;
|
||||
padding: 2.5rem;
|
||||
overflow-y: auto;
|
||||
background-color: #fff;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.chat-footer {
|
||||
padding: 24px;
|
||||
border-top: 2px solid var(--border-color);
|
||||
padding: 1.5rem 2.5rem;
|
||||
border-top: 1px solid var(--border-color);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.message { margin-bottom: 20px; max-width: 80%; display: flex; flex-direction: column; }
|
||||
.message-content { padding: 12px 20px; border-radius: 20px; font-size: 0.95rem; }
|
||||
.message { margin-bottom: 1.5rem; max-width: 70%; display: flex; flex-direction: column; }
|
||||
.message-content { padding: 1rem 1.25rem; border-radius: 18px; font-size: 14px; font-weight: 500; line-height: 1.6; }
|
||||
.message-user { margin-left: auto; align-items: flex-end; }
|
||||
.message-user .message-content { background: var(--primary-color); color: white; border-bottom-right-radius: 4px; }
|
||||
.message-user .message-content { background: var(--primary-gradient); color: white; border-bottom-right-radius: 4px; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2); }
|
||||
.message-admin { align-items: flex-start; }
|
||||
.message-admin .message-content { background: var(--bg-light); border: 2px solid var(--border-color); border-bottom-left-radius: 4px; }
|
||||
.message-admin .message-content { background: #f1f5f9; color: #334155; border-bottom-left-radius: 4px; }
|
||||
|
||||
.btn-primary { background: var(--primary-color); border: none; border-radius: 16px; width: 50px; height: 50px; }
|
||||
.form-control { border: 2px solid var(--border-color); border-radius: 16px; padding: 12px 20px; }
|
||||
.btn-send { background: var(--primary-gradient); border: none; border-radius: 14px; width: 52px; height: 52px; color: white; transition: all 0.2s; }
|
||||
.btn-send:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); }
|
||||
.form-control { border: 1.5px solid var(--border-color); border-radius: 14px; padding: 14px 20px; background: #f8fafc; font-weight: 500; }
|
||||
.form-control:focus { background: white; border-color: var(--primary); box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1); }
|
||||
|
||||
.online-indicator {
|
||||
background: #dcfce7;
|
||||
color: #15803d;
|
||||
padding: 6px 14px;
|
||||
border-radius: 100px;
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.main-content { margin-left: 80px; padding: 1.5rem; }
|
||||
.main-content { margin-left: 0; padding: 1.5rem; }
|
||||
.sidebar { display: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -103,26 +122,32 @@ $messages = $stmt->fetchAll();
|
||||
<?php include 'includes/sidebar.php'; ?>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="mb-4">
|
||||
<h2 class="fw-bold mb-1">在线技术支持</h2>
|
||||
<p class="text-muted">我们的专家团队全天候为您解决接码及充值问题</p>
|
||||
<div class="mb-4 d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h1 class="fw-bold mb-1" style="font-size: 1.5rem;">客服中心 <span class="text-muted fw-medium ms-2 fs-6">SUPPORT CENTER</span></h1>
|
||||
<p class="text-muted small mb-0 fw-medium">专业团队在线为您解答充值、收码与账户相关疑问</p>
|
||||
</div>
|
||||
<div class="online-indicator">
|
||||
<i class="fas fa-circle" style="font-size: 6px; animation: pulse 2s infinite;"></i> AGENT ONLINE
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chat-card">
|
||||
<div class="chat-container">
|
||||
<div class="chat-body" id="chatBody">
|
||||
<div class="message message-admin">
|
||||
<div class="message-content">您好!我是您的接码管家。如果您遇到任何问题,请在这里留言,我们会尽快回复。</div>
|
||||
<div class="message-content">您好,<?= htmlspecialchars($user['username']) ?>!我是您的专属技术支持。如果您遇到任何关于充值未到账、号码收不到码或其他系统问题,请随时在这里留言,我们会尽快回复您。</div>
|
||||
</div>
|
||||
<?php foreach ($messages as $msg): ?>
|
||||
<div class="message <?= $msg['sender'] === 'user' ? 'message-user' : 'message-admin' ?>">
|
||||
<div class="message-content"><?= htmlspecialchars($msg['message']) ?></div>
|
||||
<div class="small text-muted mt-2 px-1" style="font-size: 10px; font-weight: 600;"><?= date('H:i', strtotime($msg['created_at'])) ?></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="chat-footer">
|
||||
<form method="POST" class="d-flex gap-3">
|
||||
<input type="text" name="message" class="form-control" placeholder="输入您的问题..." required autocomplete="off">
|
||||
<button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane text-white"></i></button>
|
||||
<input type="text" name="message" class="form-control" placeholder="在此输入您的问题或反馈..." required autocomplete="off">
|
||||
<button type="submit" class="btn btn-send"><i class="fas fa-paper-plane"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@ -131,6 +156,19 @@ $messages = $stmt->fetchAll();
|
||||
<script>
|
||||
const chatBody = document.getElementById('chatBody');
|
||||
chatBody.scrollTop = chatBody.scrollHeight;
|
||||
|
||||
document.querySelector('form').addEventListener('submit', function() {
|
||||
setTimeout(() => {
|
||||
chatBody.scrollTop = chatBody.scrollHeight;
|
||||
}, 100);
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(0.95); opacity: 0.5; }
|
||||
70% { transform: scale(1); opacity: 1; }
|
||||
100% { transform: scale(0.95); opacity: 0.5; }
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user